Rapatrier les deux dernières lignes à côté de
Résolu
Swiss Knight
-
zipe31 Messages postés 36402 Date d'inscription Statut Contributeur Dernière intervention -
zipe31 Messages postés 36402 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour tout le monde.
j'ai un fichier texte avec ça dedans :
lambda value idx1 idx2 caract
290 0.888
380 0.518
385 0.454
445 0.139
6.53 2.54
1.12
ce sont des mesures de spectrométrie. bref.
Le truc, c'est que le ligne 1 peut être différente d'un fichier à l'autre en ce sens où elle peut avoir plus ou moins d'indices "idxn". (ici il y en a deux : "idx1" et "idx2")
Les lignes 2 à 5 dans cet exemple, contiennent des valeurs remarquables, et là il peut y avoir plusieurs lignes. Il y en a 4 ici, mais c'est un nombre variable d'un fichier à l'autre.
L'avant dernière ligne contient les indices, à savoir les valeurs de "idx1" et de "idx2" ici.
S'il y avait N indices décrits dans la 1ère lignes, il y aurait N valeurs différentes sur cette avant-dernière ligne.
Et la dernière ligne contient la valeur "caract".
j'aimerai rapatrier les valeurs des indices sous leurs noms respectifs et cette dernière ligne sous le nom "caract" pour obtenir ceci :
lambda value idx1 idx2 caract
290 0.888 6.53 2.54 1.12
380 0.518
385 0.454
445 0.139
je m'embrouille les pinceaux avec awk et les $NF $NR-1 et compagnie (il y a peut-être un moyen plus facile qu'awk aussi) :-/
Si quelqu'un a une idée facile à mettre en place, je suis preneur avec tous mes remerciements.
ps : je travaille sur ubuntu 10.04. Et la version d'awk présente sur le système est la 3.1.6.
La version de sed est là 4.2.1 si ça peut aider.
j'ai un fichier texte avec ça dedans :
lambda value idx1 idx2 caract
290 0.888
380 0.518
385 0.454
445 0.139
6.53 2.54
1.12
ce sont des mesures de spectrométrie. bref.
Le truc, c'est que le ligne 1 peut être différente d'un fichier à l'autre en ce sens où elle peut avoir plus ou moins d'indices "idxn". (ici il y en a deux : "idx1" et "idx2")
Les lignes 2 à 5 dans cet exemple, contiennent des valeurs remarquables, et là il peut y avoir plusieurs lignes. Il y en a 4 ici, mais c'est un nombre variable d'un fichier à l'autre.
L'avant dernière ligne contient les indices, à savoir les valeurs de "idx1" et de "idx2" ici.
S'il y avait N indices décrits dans la 1ère lignes, il y aurait N valeurs différentes sur cette avant-dernière ligne.
Et la dernière ligne contient la valeur "caract".
j'aimerai rapatrier les valeurs des indices sous leurs noms respectifs et cette dernière ligne sous le nom "caract" pour obtenir ceci :
lambda value idx1 idx2 caract
290 0.888 6.53 2.54 1.12
380 0.518
385 0.454
445 0.139
je m'embrouille les pinceaux avec awk et les $NF $NR-1 et compagnie (il y a peut-être un moyen plus facile qu'awk aussi) :-/
Si quelqu'un a une idée facile à mettre en place, je suis preneur avec tous mes remerciements.
ps : je travaille sur ubuntu 10.04. Et la version d'awk présente sur le système est la 3.1.6.
La version de sed est là 4.2.1 si ça peut aider.
A voir également:
- Rapatrier les deux dernières lignes à côté de
- Nombre de jours entre deux dates excel - Guide
- Deux ecran pc - Guide
- Partage de photos en ligne - Guide
- Comment faire deux colonnes sur word - Guide
- Point vert a cote de la batterie - Accueil - Protection
6 réponses
Salut,
Tiens une façon de faire avec "ed" (l'ancêtre de "sed") :
Pour que les changements soit pris en compte, soit tu rediriges le tout dans un fichier, soit tu change le ",p" (virgule comprise) final de la commande par un "w"
;-))
Tiens une façon de faire avec "ed" (l'ancêtre de "sed") :
$ cat plop lambda value idx1 idx2 caract 290 0.888 380 0.518 385 0.454 445 0.139 6.53 2.54 1.12 $ ed -s plop <<<$'$-1s/^/ /\n$s/^/ /\n$-1,$j\n$m2\n2,3j\n,p' lambda value idx1 idx2 caract 290 0.888 6.53 2.54 1.12 380 0.518 385 0.454 445 0.139 $
Pour que les changements soit pris en compte, soit tu rediriges le tout dans un fichier, soit tu change le ",p" (virgule comprise) final de la commande par un "w"
;-))
hello
avec awk
avec awk
$ awk '{x[NR]=$0}END{print x[1] ; print x[2], x[NR-1], x[NR] ; for (n=3;n<NR-1;)print x[n++]}' fichier lambda value idx1 idx2 caract 290 0.888 6.53 2.54 1.12 380 0.518 385 0.454 445 0.139 $
code awk qui traite tous les fichiers en 1 fois, les nouveaux fichiers ont un .2 ajouté, modifiable bien sûr
$ awk 'BEGIN{for (n=1;n<ARGC;n++){f=ARGV[n]; i=0;while("cat " f | getline)x[++i]=$0 ; print x[1] "\n" x[2], x[i-1], x[i] > f ".2" ; for (m=3;m<i-1;)print x[m++]> f ".2"}}' fichier* $
okay, merci pour ta réponse, alors, en faisait ceci :
$ ed -s iIndices_sample_tmpET1.txt <<<$'$-1s/^/ /\n$s/^/ /\n$-1,$j\n$m2\n2,3j\n,p' > out.txt
ça a l'air de tout bien fonctionner, même si le nombre des indices varie ou que les premières lignes, dès la 2ème, ne sont pas toujours présentent en même quantité.
merci beaucoup, j'espère savoir faire ça tout seul un jour :s
$ ed -s iIndices_sample_tmpET1.txt <<<$'$-1s/^/ /\n$s/^/ /\n$-1,$j\n$m2\n2,3j\n,p' > out.txt
ça a l'air de tout bien fonctionner, même si le nombre des indices varie ou que les premières lignes, dès la 2ème, ne sont pas toujours présentent en même quantité.
merci beaucoup, j'espère savoir faire ça tout seul un jour :s
même si le nombre des indices varie
Oui, peu importe.
ou que les premières lignes, dès la 2ème, ne sont pas toujours présentent en même quantité.
Tu entends quoi par là exactement ??? Si c'est les lignes après la 2nde et avant l'avant-dernière, oui, on s'en fiche aussi, peu importe leur nombre.
La condition c'est que la 1ère et 2ème ligne soient immuables ainsi que la dernière et l'avant-dernière, non ?
Oui, peu importe.
ou que les premières lignes, dès la 2ème, ne sont pas toujours présentent en même quantité.
Tu entends quoi par là exactement ??? Si c'est les lignes après la 2nde et avant l'avant-dernière, oui, on s'en fiche aussi, peu importe leur nombre.
La condition c'est que la 1ère et 2ème ligne soient immuables ainsi que la dernière et l'avant-dernière, non ?
Arf mince, le problème est que je lance cette commande depuis un autre soft, ça risque d'être vite trop tordu pour faire le script bash et j'ai assez peu envie de faire appel à un script situé dans un autre fichier pour éviter d'avoir plusieurs fichiers à transférer en cas de mises à jour du script principal.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Salut,
entre temps j'ai eu de l'aide ailleurs et ce bout de code :
ça marche assez bien aussi, le petit hic c'est qu'il faut que je sois dans le dossier contenant les fichiers, et que j'aimerai cibler cette commande sur un dossier préciser, mettons ~/username/data, et ce, peu importe oû je me situe dans l'arborescence.
entre temps j'ai eu de l'aide ailleurs et ce bout de code :
awk 'BEGIN {OFS=","} FNR == 1 { if( j==1 ) { ligne[2]=ligne[2] OFS ligne[nb_lignes-1] OFS ligne[nb_lignes] for(i=1; i<=nb_lignes-2; i++) print ligne[i] > nom_fic } nom_fic=FILENAME } { ligne[FNR]=$0; gsub(" ",",",ligne[FNR]); nb_lignes=FNR; j=1 } END { ligne[2]=ligne[2] OFS ligne[nb_lignes-1] OFS ligne[nb_lignes] for(i=1; i<=FNR-2; i++) print ligne[i] > nom_fic }' *.txt
ça marche assez bien aussi, le petit hic c'est qu'il faut que je sois dans le dossier contenant les fichiers, et que j'aimerai cibler cette commande sur un dossier préciser, mettons ~/username/data, et ce, peu importe oû je me situe dans l'arborescence.
Voilà une solution avec "sed" qui permet de cibler tous les fichiers d'un même répertoire et de modifier lesdits fichiers. L'option de sauvegarde "-i.bak" est facultative, mais permet néanmoins de faire un backup de chaque fichier.
J'ai créé 3 fichiers différents en nombre de "idxn" et de lignes intermédiaires afin de vérifier que tous les cas sont pris en compte.
J'ai créé 3 fichiers différents en nombre de "idxn" et de lignes intermédiaires afin de vérifier que tous les cas sont pris en compte.
$ head f* ==> f1 <== lambda value idx1 idx2 caract 290 0.888 380 0.518 385 0.454 445 0.139 6.53 2.54 1.12 ==> f2 <== lambda value idx1 idx2 idx3 caract 290 0.888 380 0.518 385 0.454 445 0.139 550 0.122 6.53 2.54 1.23 1.12 ==> f3 <== lambda value idx1 idx2 idx4 idx5 caract 290 0.888 301 0.565 380 0.518 385 0.454 445 0.139 500 0.123 654 0.369 7.66 6.21 6.53 2.54 1.12 $ cat script.sed 1 { N h d } :z N $ !b z s/(.*)\n(.*)\n(.*)/\2 \3\n\1/ H g s/\n/ /2 $ sed -r -i.bak -f script.sed f* $ head f* ==> f1 <== lambda value idx1 idx2 caract 290 0.888 6.53 2.54 1.12 380 0.518 385 0.454 445 0.139 ==> f1.bak <== lambda value idx1 idx2 caract 290 0.888 380 0.518 385 0.454 445 0.139 6.53 2.54 1.12 ==> f2 <== lambda value idx1 idx2 idx3 caract 290 0.888 6.53 2.54 1.23 1.12 380 0.518 385 0.454 445 0.139 550 0.122 ==> f2.bak <== lambda value idx1 idx2 idx3 caract 290 0.888 380 0.518 385 0.454 445 0.139 550 0.122 6.53 2.54 1.23 1.12 ==> f3 <== lambda value idx1 idx2 idx4 idx5 caract 290 0.888 7.66 6.21 6.53 2.54 1.12 301 0.565 380 0.518 385 0.454 445 0.139 500 0.123 654 0.369 ==> f3.bak <== lambda value idx1 idx2 idx4 idx5 caract 290 0.888 301 0.565 380 0.518 385 0.454 445 0.139 500 0.123 654 0.369 7.66 6.21 6.53 2.54 1.12 $