#1 Le 01/10/2012, à 17:55
- thib1984
[Résolu] remplacement de chaines à une position donnée
Bonjour,
je suis un peu perdu
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
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
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
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
Magnifique! Ca va beaucoup plus vite, et c'est bien plus joli!
Bon comme il faut apprendre de plus fort que soi je vais essayer de comprendre la commande. Si tu repasses par ici, n'hésite pas à me corriger
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
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