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 01/10/2012, à 17:55

thib1984

[Résolu] remplacement de chaines à une position donnée

Bonjour,

je suis un peu perdu sad
Je dois faire une manipulation sur chaque ligne d'un fichier.
Si les caractères 25 à 28 sont "    " alors je dois les remplacer par "0000".
Si les caractères 22 à 24 sont "   " alors je dois les remplacer par "234"
et ainsi de suite.

J'ai pensé à quelque chose de ce type

while read line; 
do
len=$(expr "$line" : '.*') # length of line
echo $len;
f1="$(echo "$line" | cut -c1-21)"
f2="$(echo "$line" | cut -c22-24)"
f2=$(echo "$f2"|sed 's/\   /234/g')
f3="$(echo "$line" | cut -c25-28)"
f3=$(echo "$f3"|sed 's/\    /0000/g')
f4="$(echo "$line" | cut -c64-$len)"
printf "%s%s%s\n" "$f1" "$f2" "$f3" "$f4">> $1.new
done

mais c'est atrocement lent... Une seconde par ligne sad
Auriez vous une idée pour accélerer le processus?
Je pense que awk ferait l'affaire mais je ne comprends pas grand chose....

Dernière modification par thib1984 (Le 01/10/2012, à 20:44)

Hors ligne

#2 Le 01/10/2012, à 18:12

Watael

Re : [Résolu] remplacement de chaines à une position donnée

salut,

man bash /Parameter Expansion


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

Hors ligne

#3 Le 01/10/2012, à 18:52

thib1984

Re : [Résolu] remplacement de chaines à une position donnée

Je ne suis pas sûr de bien comprendre ta réponse smile
Si tu m'invites à consulter la documentation bash, je ne crois pas que tu réponds à la question en fait.
Il manque en effet un < $1 après le done

soit

done < $1

Bref, le souci n'est pas d'avoir un script qui fonctionne (en l'occurence le mien marche) mais un script qui aille plus vite car le mien semble lent sad
J'ai donné un rapide aperçu de mon code afin de vous montrer sa philosophie, c'est tout... Il manque des morceaux etc...

Hors ligne

#4 Le 01/10/2012, à 18:56

Watael

Re : [Résolu] remplacement de chaines à une position donnée

ça ira déjà plus vite en 100% bash
=> man bash /Parameter Expansion
au lieu de tous ces `cut'


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

Hors ligne

#5 Le 01/10/2012, à 19:29

pingouinux

Re : [Résolu] remplacement de chaines à une position donnée

Bonjour,
Je te propose ceci :

sed -r 's/^(.{21})   (.*)$/\1234\2/;s/^(.{24})    (.*)$/\10000\2/' fichier

ou même plus simple

sed -r 's/^(.{21})   /\1234/;s/^(.{24})    /\10000/' fichier

Dernière modification par pingouinux (Le 01/10/2012, à 20:07)

Hors ligne

#6 Le 01/10/2012, à 20:32

thib1984

Re : [Résolu] remplacement de chaines à une position donnée

cool Magnifique! Ca va beaucoup plus vite, et c'est bien plus joli!

Bon comme il faut apprendre de plus fort que soi tongue je vais essayer de comprendre la commande. Si tu repasses par ici, n'hésite pas à me corriger smile


sed -r

syntaxe étendue (=pour les expressions régulières?)

 's

subsitution

/^(.{21})   (.*)$

ce qu'on va remplacer, un début de ligne, suivi de 21 caractères quelconques puis 4 espaces puis un nombre indéterminé de caractères, jusqu'à la fin de la ligne

/\1234\2/

ce par quoi on remplace : le "234" évidemment mais \1 et \2 'remettent' le début et la fin de notre fichier... et là je ne suis pas sûr de saisir. \1 = 'le ^(.{21})' et \2 ='(.*)'? J'ai l'impression que c'est ça en comparant les deux expressions que tu m'as proposé.

;s/^(.{24})    (.*)$/\10000\2/'

meme raisonnement pour la deuxième expression

fichier

le nom du fichier à "travailler"

Merci encore smile

Hors ligne

#7 Le 01/10/2012, à 20:49

pingouinux

Re : [Résolu] remplacement de chaines à une position donnée

@thib1984 #6 : C'est exactement ça !

Dans ton script du #1, tu utilisais plusieurs fois cut pour chaque ligne. cut est une commande adaptée pour traiter tout un fichier.
D'autre part, tu aurais pu simplifier :

f3="$(echo "$line" | cut -c25-28)"
f3=$(echo "$f3"|sed 's/\    /0000/g')

pouvait s'écrire

f3="$(cut -c25-28 <<<"$line" | sed 's/    /0000/')

Ajouté :
Es-tu sûr d'être obligé de compter les caractères ? Tu peux éventuellement montrer quelques lignes de ton fichier pour voir s'il n'y a pas une autre méthode.

Dernière modification par pingouinux (Le 02/10/2012, à 06:19)

Hors ligne