[Shell] Insertion de caractères

Insertion de caractères [Shell] - Shell/Batch - Programmation

Marsh Posté le 09-03-2006 à 16:00:51    

Bonjour  :hello:  
Voilà mon pb...j'suis pas très calée en shell...j'ai donc un peu de mal à résoudre mon pb  :??: ...  
J'ai un fichier text qui est un export en colonne du type  
"A" "B" "C" "D"  
"1" "2" "3" "4"  
Ce que je veux, c'est créer un shell pour insérer "X" en 3 eme colonne de chaque ligne par exemple, de manière à obtenir  
"A" "B" "C" "X" "D"  
"1" "2" "3" "X" "4"  
Si quelqu'un peut m'aider, ça serait bien urbain.
MERCI

Reply

Marsh Posté le 09-03-2006 à 16:00:51   

Reply

Marsh Posté le 13-03-2006 à 15:07:59    

Bon, j'ai un début de réponse....
 
cat toto.txt | awk 'BEGIN{FS=" "}{printf ("%s %s %s \"X\" %s\n",$1,$2,$3,$4)}' > .tototmp  
mv .tototmp toto.txt  
 
Ca ca marche bien pour insérer mes colonnes... Mais ca tient compt d'une hypothèse, c'est que je connais d'avance le nombre de champs! Or dans mon cons, le nombre de champs est inconnu et variable d'une ligne a l'autre.
Plus précisément, j'ai 10 champs fixés, et c'est parmis ceux ci que je dois insérer mes colonnes, suivis de 1 à 12 champs, selon le cas...
Il me faudrait donc trouver une formule pour dire de renvoyer mes champs du 10eme au dernier (qui se dit NF je crois, d'après mes recherches..)
Je vous remercie d'avance.

Reply

Marsh Posté le 13-03-2006 à 15:39:46    

je connais pas bien awk, mais avec perl tu peux faire un truc de ce genre :

cat toto.txt | perl -n -e '/^((\S+\s+){3})(.*)$/; print $1, "X ", $3, "\n";'


 
Tu peux aussi sans doute jouer avec les commandes cut et paste


---------------
TriScale innov
Reply

Marsh Posté le 13-03-2006 à 19:49:39    

azerty169 a écrit :

Bonjour  :hello:  
Voilà mon pb...j'suis pas très calée en shell...j'ai donc un peu de mal à résoudre mon pb  :??: ...  
J'ai un fichier text qui est un export en colonne du type  
"A" "B" "C" "D"  
"1" "2" "3" "4"  
Ce que je veux, c'est créer un shell pour insérer "X" en 3 eme colonne de chaque ligne par exemple, de manière à obtenir  
"A" "B" "C" "X" "D"  
"1" "2" "3" "X" "4"  
Si quelqu'un peut m'aider, ça serait bien urbain.
MERCI


 
En fait, faut bien que tu comprennes que le shell en lui-même est très limité. Il faut l'associer à d'autres commandes unix pour arriver à résoudre tous les pb que tu devras résoudre
 

#!/bin/sh
# Stockage du fichier à traiter dans le buffer 3 (0, 1 et 2 étant déjà pris par défaut)
exec 3<fichier_a_traiter
 
# Lecture du buffer 3 (donc du fichier) ligne à ligne
while read lig 0<&3
do
     # Extraction du début de la ligne (avant le "X" )
     deb=`echo $lig |cut -d' ' -f1-3`
 
     # Extraction de la fin de la ligne (après le "X" )
     fin=`echo $lig |cut -d' ' -f3-`
 
     # Ecriture de la nouvelle ligne
     echo "$deb X $fin"
done >nouveau_fichier


 
Ensuite, si "nouveau fichier" te convient, tu le renommes à la place de l'ancien
 
Cours complet et en français de shell ici: http://fr.lang.free.fr/cours/Shell_v1.4.pdf
 

azerty169 a écrit :

Bon, j'ai un début de réponse....
 
cat toto.txt | awk 'BEGIN{FS=" "}{printf ("%s %s %s \"X\" %s\n",$1,$2,$3,$4)}' > .tototmp  
mv .tototmp toto.txt  
 
Ca ca marche bien pour insérer mes colonnes... Mais ca tient compt d'une hypothèse, c'est que je connais d'avance le nombre de champs! Or dans mon cons, le nombre de champs est inconnu et variable d'une ligne a l'autre.


Ben avec "cut -f3-" ça part du 3° champ de la ligne jusqu'à la fin...
 

azerty169 a écrit :

Il me faudrait donc trouver une formule pour dire de renvoyer mes champs du 10eme au dernier (qui se dit NF je crois, d'après mes recherches..)


Bon, FS=" " est inutile car c'est déjà comme ça par défaut. Et le pipe est inutile puisque "awk" peut traiter des fichiers. Mais sinon, NF (Number Field) est tout à fait ça. Sauf qu'il te faut programmer une boucle puisque tu ne connais pas à l'avance combien t'en auras.
Une boucle avant le X et une boucle après...
Bon, imaginons que tu doives insérer le "X" après la 9° position (et avant la 10°)
awk '{for (i=1; i <= 9; i++) {printf("%s ", $i)} printf("X" ); for (i=10; i <= NF; i++) {printf(" %s", $i);} printf("\n" );} toto.txt
 
Un poil plus compliqué... mais encore lisible. Au delà, vaut mieux écrire tout ton script dans un fichier "toto.awk" et taper "awk -f toto.awk toto.txt".


Message édité par Sve@r le 13-03-2006 à 19:57:13
Reply

Marsh Posté le 17-03-2006 à 17:11:01    

Merci, ca marche!

Reply

Marsh Posté le 17-03-2006 à 18:22:11    


Tiens, je te croyais définitivement parti...
 

azerty169 a écrit :

Merci, ca marche!


L'important n'est pas que nos scripts fonctionnent (en général, les gens qui répondent le font parce qu'ils connaissent la réponse donc leur réponse fonctionne toujours)... l'important est que tu aies compris le principe de l'algorithmie spécifique à ton problème et la façon de convertir cette algorithmie en shell (ou en awk ou en perl ou en C ou en...)
 
On sait que nos scripts fonctionnent. On espère simplement que si demain t'as un autre problème plus ou moins analogue, tu puisses t'en sortir sans nous... et si tu t'en sors pas on sera encore prêt à t'aider...


Message édité par Sve@r le 17-03-2006 à 18:23:09

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed