Moulinette awk (ajout de champs) pour un newb
Résolu
matthieu
-
matthieu -
matthieu -
Bonjour,
je ne suis pas du tout informaticien, ce qui explique que je bute deja sur ce probleme simplissime:
J'ai un fichier de taille variable, que je veux reecrire en rajoutant des lignes.
Ex:
j'ai le fichier ;
********
toto1
titi
********
toto2
tutu
********
toto3
tete
********
Je veux arriver a ca :
*******
toto1
totoajouté
titi
*******
toto2
totoajouté
tutu
********
(...)
Le probleme est que je ne connais pas a l'avance le nombre de partie entre lignes (******)
et mes connaissances en awk sont très basiques.
Je peux le faire en fortran, mais je trouve que awk est quand meme plus elegant et efficace dans une chaine en shell.
merci pour votre aide, et desole pour le niveau de la question!
je ne suis pas du tout informaticien, ce qui explique que je bute deja sur ce probleme simplissime:
J'ai un fichier de taille variable, que je veux reecrire en rajoutant des lignes.
Ex:
j'ai le fichier ;
********
toto1
titi
********
toto2
tutu
********
toto3
tete
********
Je veux arriver a ca :
*******
toto1
totoajouté
titi
*******
toto2
totoajouté
tutu
********
(...)
Le probleme est que je ne connais pas a l'avance le nombre de partie entre lignes (******)
et mes connaissances en awk sont très basiques.
Je peux le faire en fortran, mais je trouve que awk est quand meme plus elegant et efficace dans une chaine en shell.
merci pour votre aide, et desole pour le niveau de la question!
A voir également:
- Moulinette awk (ajout de champs) pour un newb
- Demande d'ajout snap qui disparait ✓ - Forum Snapchat
- Ajout rapide snap - Forum Snapchat
- Word mettre à jour tous les champs ✓ - Forum Word
- MAJ automatique de champs répétitifs dans un document Word - Forum Word
- Ajout snap sans rien d'écrit - Forum Snapchat
7 réponses
hello
$ cat a1 ******** toto1 titi ******** toto2 tutu ******** toto3 tete ******** $ awk '{print $0} ; /^toto/ {print "totoajoute"}' < a1 ******** toto1 totoajoute titi ******** toto2 totoajoute tutu ******** toto3 totoajoute tete ******** $
après toute ligne qui commence par 3 *, on lit la suivante et on l'imprime 2 fois
$ cat a1 **** nitrate .true. 0.0 ***** phosphate .false. 0.0 ***** choucroute .true. 1.1 $ awk '{print $0} ; /^\*\*\*/ {getline ; print $0 ; print $0}' < a1 **** nitrate nitrate .true. 0.0 ***** phosphate phosphate .false. 0.0 ***** choucroute choucroute .true. 1.1
haha, merci pour la choucroute dubcek, on y est presque (faut etre patient avec les newb')
Quand on veut simplifier son probleme pour etre lu, on rajoute d'autre soucis
En fait,
je dois recopier nitrate, mais aussi rajouter 0.0 dans la 5eme ligne par exemple
(certains elements sont recopies, d'autres sont inseres)
****
nitrate
.true.
0.0
*****
(...)
doit donner (en resume)
****
nitrate
nitrate
.true.
.true.
0.0
1000.
*****
(...)
Ton script marche pour la premiere ligne apres ***, mais pour une autre ?
la commande getline est un peu obscure pour moi.
Merci de ton temps deja passe, je vais essayer de bidouiller a partir de tes infos, et la doc awk (c'est velu quand meme!)
Quand on veut simplifier son probleme pour etre lu, on rajoute d'autre soucis
En fait,
je dois recopier nitrate, mais aussi rajouter 0.0 dans la 5eme ligne par exemple
(certains elements sont recopies, d'autres sont inseres)
****
nitrate
.true.
0.0
*****
(...)
doit donner (en resume)
****
nitrate
nitrate
.true.
.true.
0.0
1000.
*****
(...)
Ton script marche pour la premiere ligne apres ***, mais pour une autre ?
la commande getline est un peu obscure pour moi.
Merci de ton temps deja passe, je vais essayer de bidouiller a partir de tes infos, et la doc awk (c'est velu quand meme!)
getline lit la ligne suivante, je peux faire:
awk '{print $0} ; /^\*\*\*/ {getline ; print $0 "\n" $0 ; getline ; print $0 "\n" $0 "\n" "99.0" }' < a1 **** nitrate nitrate .true. .true. 99.0 0.0 ***** phosphate phosphate .false. .false. 99.0 0.0 *****
merci encore pour ta reactivite et ta patience (vu la clarte de mon expose)
Reste un dernier point que je vais essayer de corriger, vu tout ce que tu m'a donne
le fichier d'entree se termine par :
(...)
blabla
*************
et je voudrai qu'il se termine de la meme facon une fois reecrit, en fait que le script awk ne s'applique pas a la derniere occurence de ***** (sinon il recopie les blancs encore apres). C'est possible?
Je pensais supprimer les x dernieres lignes (toujours avec awk, une fois le script execute)
Quoiqu'il en soit, merci beaucoup, avec ca je me debrouillerai (j'allais partir dans des boucles for...!)
Reste un dernier point que je vais essayer de corriger, vu tout ce que tu m'a donne
le fichier d'entree se termine par :
(...)
blabla
*************
et je voudrai qu'il se termine de la meme facon une fois reecrit, en fait que le script awk ne s'applique pas a la derniere occurence de ***** (sinon il recopie les blancs encore apres). C'est possible?
Je pensais supprimer les x dernieres lignes (toujours avec awk, une fois le script execute)
Quoiqu'il en soit, merci beaucoup, avec ca je me debrouillerai (j'allais partir dans des boucles for...!)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
il faut connaitre le nombre de lignes et on teste, si il y a égalité avec la ligne courante (NR) on sort
$ L=$(wc -l < a1) $ awk '{print $0} ; /^\*\*\*/ {getline ; if (NR == '"$L"') exit ; print $0 "\n" $0 ; getline ; print $0 "\n" $0 "\n" "99.0" }' < a1 **** nitrate nitrate .true. .true. 99.0 0.0 ***** phosphate phosphate .false. .false. 99.0 0.0 ***** $
Salut,
Et avec "sed" (désolé dubcek ;-)) ) :
;-))
Et avec "sed" (désolé dubcek ;-)) ) :
jp@MDK:~/tmpfs ssh$ cat fich **** nitrate .true. 0.0 ***** phosphate .false. 0.0 ***** choucroute .true. 1.1 jp@MDK:~/tmpfs ssh$ sed -i.bak '/\*\+/{n;/^$/q;s/.*/&\n&/;n;s/.*/&\n&\n99.0/}' fich jp@MDK:~/tmpfs ssh$ cat fich **** nitrate nitrate .true. .true. 99.0 0.0 ***** phosphate phosphate .false. .false. 99.0 0.0 ***** choucroute choucroute .true. .true. 99.0 1.1 jp@MDK:~/tmpfs ssh$
;-))
En fait, en voulant simplifier mon exemple, j'ai introduit un cas particulier.
Le nombre de ligne entre les ******** est toujours le meme, mais les champs peuvent etre differents (pas tous des "toto..." )
il s'agit pour etre precis de nom de substance (ex :
****
nitrate
.true.
0.0
*****
phosphate
.false.
0.0
*****
(...)
qui doit devenir par exemple
****
nitrate
nitrate
.true.
0.0
*****
(...)
Je pensais d'abord compter le nombre de substances (nb de lignees contenant **** -1)
puis faire une boucle a partir de la premiere occurence de "*****" (attention la ligne peut faire 20 "*")
je vois a peu pres comment faire, mais ce sont les "mots" qui me manquent !
desole pour cette mauvaise explication initiale
merci encore pour votre aide