Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 25/03/2021, à 10:44

ar barzh paour

[Résolu] récupération des champs d'une chaine

hello bonjour à tous
j'ai encore un petit soucis pour récupérer (en bash) des champs dans une chaîne qui peut être bizarre
exemple de chaîne

R3='xxxxxxxxx!yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!'

# les caractères x peuvent être différents et peuvent être ou non des !
# les caractères suivants (y,z,t,u,v,a,b,c,d) peuvent être différents mais ne sont pas des !
# je cherche à extraire la chaine 'yyy!....!ddd'

# je trouve que c'est impossible
# sauf par exemple si on connaît le nombre de champs qu'il y a après le ! des xxxxxx

# (le séparateur de champ est ! sauf que xxxxxx peut aussi contenir des ! en nombre inconnu)
# exemple pour ci-dessus
# j'ai essayé avec awk, j'y arrive mais assez compliqué
# j'ai finalement utilisé rev , il y a peut-être plus efficace

inverse=$(rev <<<"$R3")
nb_champ=9
res=""
oldIFS="$IFS"
IFS="!"
tableau=($inverse)
IFS="$OldIFS"
for ((i=$nb_champ;i>0;i--)) ;do res=$res${tableau[$i]}"!" ; done
echo $res # => yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!

en terminant d'écrire le post je crois bien qu'avec awk et NF on pourrait y arriver
on peut faire awk  '{print $NF}' awk'{print $1}' etc
mais a-t-on le droit de faire awk  '{print variable}' ?

Dernière modification par ar barzh paour (Le 25/03/2021, à 17:47)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#2 Le 25/03/2021, à 11:10

Watael

Re : [Résolu] récupération des champs d'une chaine

salut,

les x sont-ils en nombres constants ?

on peut en effet se passer de rev

$ IFS='!' read -ra ar <<<"$R3"
$ for ((i=${#ar[*]};i>=${#ar[*]}-9;i--)); do test -n "${ar[i]}" && echo "${ar[i]}"; done
ddd
ccc
bbb
aaa
vvv
uuu
ttt
zzz
yyy
$

Dernière modification par Watael (Le 25/03/2021, à 11:10)


Connected \o/
Welcome to sHell. · eval is evil.

En ligne

#3 Le 25/03/2021, à 11:14

kamaris

Re : [Résolu] récupération des champs d'une chaine

ar barzh paour a écrit :

# je trouve que c'est impossible
# sauf si on connaît le nombre de champs qu'il y a après le ! des xxxxxx

Oui c'est impossible : il faut une contrainte supplémentaire.
Le nombre de champs en est une possible, une autre serait de connaître un morceau de la chaine yyy qui succède au premier « vrai séparateur » !, et d'utiliser des expressions régulières avancées, de type Perl.
Pour ce qui est de awk, avec la contrainte du nombre de champs, tu peux faire

rev <<<"$R3" | awk 'BEGIN{OFS=FS="!"} NF=9'

Hors ligne

#4 Le 25/03/2021, à 11:22

Hizoka

Re : [Résolu] récupération des champs d'une chaine

Je partirai sur une boucle inversée comme le préconise Watael.

Si le nombre de ! est fixe à partir de yyy alors ça fonctionne :

mapfile -td '!' caca <<< 'xxxxxxxxx!yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!'
echo "${caca[-2]}" # ddd
echo "${caca[-10]}" #yyy
mapfile -td '!' caca <<< 'xxxxx!x!xxx!yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!'
echo "${caca[-2]}" # ddd
echo "${caca[-10]}" #yyy

Dernière modification par Hizoka (Le 25/03/2021, à 11:24)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#5 Le 25/03/2021, à 11:55

pingouinux

Re : [Résolu] récupération des champs d'une chaine

Bonjpour,
Bonjour,
Avec sed :

sed -r 's/.*!(([^!]+!){8}[^!]+)!$/\1/' <<<"$R3"

Dernière modification par pingouinux (Le 25/03/2021, à 14:05)

Hors ligne

#6 Le 25/03/2021, à 14:57

ar barzh paour

Re : [Résolu] récupération des champs d'une chaine

ok merci pour toutes vos réponses que je vais lire à tête reposée
quelques réponses :
les chaînes sont aléatoires , en valeur et en longueur
on a réellement
S1!S2!un répertoire!une chaîne!un entier!suivis de 6 booléens
S1 et S2 sont le résultat de saisies  manuelles (donc n'importe quoi  * , ? ,  $ , ^, ! , !!!!!, chaine /avec ou sans espace)
les autres ne comporte pas de !
répertoire est de format répertoire /.....  ou  .  ou ~/....  ou 
la chaine qui suit .*\.txt|.*\.py|.......
là ou j'ai butté c'est effectivement le cas ou on saisissait ! ou !! ou !!! ou .....

en tout cas pingouinux !!!!! ça je n'aurais pas trouvé

sed -r 's/.*!(([^!]+!){8}[^!]+)!$/\1/' <<<"$R3"
yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd

pour moi je décode
  .*!         : n'importe quoi  suivi de !                 xxxxx!
  (                                                        mise en mémoire
  ([^!]+!){8} : (n'importe quoi sauf ! suivi de !) 8 fois  yyy! à ccc!
  [^!]+       : n'importe quoi sauf !                      ddd
  )
  !$          : se terminant par !
et comme j'ai aussi besoin du début , j'en profite

sed -E 's/(.*!)(([^!]+!){8}[^!]+)!$/\1/' <<<"$R3"
xxxxxxxxx!
sed -E 's/(.*!)(([^!]+!){8}[^!]+)!$/\2/' <<<"$R3"
yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd

@hizoka
mapfile est aussi intéressant , car j'utilise ensuite les différentes valeurs
ok pour -2 à -10 mais pas pour décoder le début xxxx qui peut comporter des !

for i in -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 ;do
 echo $i "${champ[$i]}"
 done
-1 

-2 ddd
-3 ccc
-4 bbb
-5 aaa
-6 vvv
-7 uuu
-8 ttt
-9 zzz
-10 yyy
-11 xxxxxxxxx

Dernière modification par ar barzh paour (Le 25/03/2021, à 18:10)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 22.04, 22.04, 23.04
Portable1 : Intel(R) Core(TM)2 Duo CPU     T6570  @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 23.04 ( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#7 Le 26/03/2021, à 21:25

pingouinux

Re : [Résolu] récupération des champs d'une chaine

Une solution en python :

python3 -c "import re; print(re.search('!(([^!]+!){9})$','$R3').group(1)[:-1])"

Hors ligne

#8 Le 26/03/2021, à 23:59

Hizoka

Re : [Résolu] récupération des champs d'une chaine

mapfile -td '!' caca <<< 'xxxxx!x!xxx!yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!'
echo "${caca[-2]}" # ddd
echo "${caca[-10]}" #yyy

Nb=$((${#caca[@]} - 10)) # 10 car c'est le nombre de ! par défaut
echo "${caca[@]::${Nb}}" #xxxxx x xxx

ou

var='xxxxx!x!xxx!yyy!zzz!ttt!uuu!vvv!aaa!bbb!ccc!ddd!'
ddd="${var%\!*}" ddd="${ddd##*\!}"
echo "$ddd" # ddd

yyy="${var%\!*\!*\!*\!*\!*\!*\!*\!*\!*}" yyy="${yyy##*\!}"
echo "$yyy" # yyy

xxx="${var%\!*\!*\!*\!*\!*\!*\!*\!*\!*\!*}"
echo "$xxx" # xxxxx!x!xxx

KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne