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 09/10/2011, à 20:45

csm

Transformer des lignes automatiquement avec un script sh

Bonsoir.

Je dispose d'un fichier ASCII qui contient des lignes sous cette forme :

"Exemple","b01",6681,10,25,4685,135,134,10,194,5609,9755,315,0,23,14,9,30,8,10,0,5,0,0,0,0,27653

Je souhaiterai automatiser certaines modifications sur ce fichier via un script shell. En l'occurrence réaliser les opérations suivantes :

1. Suppression des guillemets (" ")
2. Remplacement des virgule (,) par _&_ ([espace]&[espace])
3. Ajout en fin de ligne de \\_\hline

Donc en résultat :

Exemple & b01 & 6681 & 10 & 25 & 4685 & 135 & 134 & 10 & 194 & 5609 & 9755 & 315 & 0 & 23 & 14 & 9 & 30 & 8 & 10 & 0 & 5 & 0 & 0 & 0 & 0 & 27653\\ \hline

Quels outils utiliser pour le faire (mes connaissances en shell script sont limitées) ?

L'idéal serait d'avoir, au final, :

~$ script.sh fichiersource fichierdesortie

Merci !

Dernière modification par csm (Le 09/10/2011, à 20:55)

Hors ligne

#2 Le 09/10/2011, à 20:49

wido

Re : Transformer des lignes automatiquement avec un script sh

Bonjour,
utilise sed

par exemple:

$ export chaine="ceci est une chaine de caractères"
$ echo $chaine | sed -e "s/ /_/g"
 ceci_est_une_chaine_de_caractères

Hors ligne

#3 Le 09/10/2011, à 21:01

Haleth

Re : Transformer des lignes automatiquement avec un script sh

Tu peux faire ca avec sed, du genre :

sed s/chaines1/chaine2/g fichier1 > fichier2

Ceci remplace toute les occurrences de chaine1 dans le fichier fichier1 par chaine2, le resultat est placé dans le fichier2.
Donc, pour le 1 :

sed s/`\"//g fichier1 > fichier2

Pour le 2 : (on utilise -e pour les ", afin d'isoler la ligne du shell)

sed -e "s/\,/\ &\ /g" fichier2 > fichier3

Pour le 3 :
Je sais pas encore


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#4 Le 09/10/2011, à 21:40

Postmortem

Re : Transformer des lignes automatiquement avec un script sh

Salut,

sed -e 's/"//g' -e 's/,/ \& /g' -e 's/$/\\\\ \\hline/' fichiersource > fichiersortie

Edit :

Haleth a écrit :

Pour le 2 : (on utilise -e pour les ", afin d'isoler la ligne du shell)

Non, le -e introduit une commande dans sed. Et il n'est pas obligatoire quand il n'y a qu'une commande.
Les " permettent de ne passer "qu'un mot" à sed. Sinon le shell fait un découpage s'il y a des espaces et sed reçoit 2 mots et donc considère ça comme 2 commandes ou options.
Sinon, dans sed, je préfère utiliser des simples quotes plutôt que des doubles. En effet, entre doubles quotes, les caractères $, \ et ` gardent leur signification spéciale pour le shell, ce qui n'est pas le cas entre simples quotes.
Après, si on a besoin d'une variable dans une commande sed, les doubles quotes sont donc pratiques.

Dernière modification par Postmortem (Le 09/10/2011, à 22:04)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#5 Le 09/10/2011, à 22:40

Levi59

Re : Transformer des lignes automatiquement avec un script sh

en shell bash et sans sed :

#!/bin/bash

while read
do
    REPLY=${REPLY//\"/}
    Fichier+=( "${REPLY//,/ & }" )
done < fichiersource.txt

printf '%s\\\\ \\hline\n' "${Fichier[@]}" > fichiersortie.txt  # qui peut être le fichier source

exit 0

edit
oublie de guillemets

edit2
plus court

Dernière modification par Levi59 (Le 10/10/2011, à 02:36)

Hors ligne

#6 Le 09/10/2011, à 23:30

Haleth

Re : Transformer des lignes automatiquement avec un script sh

Postmortem a écrit :

Salut,
Non, le -e introduit une commande dans sed. Et il n'est pas obligatoire quand il n'y a qu'une commande.
Les " permettent de ne passer "qu'un mot" à sed. Sinon le shell fait un découpage s'il y a des espaces et sed reçoit 2 mots et donc considère ça comme 2 commandes ou options.
Sinon, dans sed, je préfère utiliser des simples quotes plutôt que des doubles. En effet, entre doubles quotes, les caractères $, \ et ` gardent leur signification spéciale pour le shell, ce qui n'est pas le cas entre simples quotes.
Après, si on a besoin d'une variable dans une commande sed, les doubles quotes sont donc pratiques.

Tu as tout a fait raison, ce que je voulais dire, c'est que dans le cas présent, les " empechent bash d'interpreter le & (et donc de lancer la commande en arriere plan)
Merci pour la précision !


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#7 Le 10/10/2011, à 14:16

csm

Re : Transformer des lignes automatiquement avec un script sh

Levi59 a écrit :

en shell bash et sans sed :

#!/bin/bash

while read
do
    REPLY=${REPLY//\"/}
    Fichier+=( "${REPLY//,/ & }" )
done < fichiersource.txt

printf '%s\\\\ \\hline\n' "${Fichier[@]}" > fichiersortie.txt  # qui peut être le fichier source

exit 0

edit
oublie de guillemets

edit2
plus court

Merci de votre aide ... complète ! Même si je comprenais mieux la première version du script que la nouvelle.

Est-il possible de transformer les noms de fichiers en variables ?

Sur le modèle évoqué ci-dessus :

~$ script.sh fichiersource fichierdesortie

Suffit-il de remplacer les noms par $1 et $2 ?

#!/bin/bash

while read
do
    REPLY=${REPLY//\"/}
    Fichier+=( "${REPLY//,/ & }" )
done < $1

printf '%s\\\\ \\hline\n' "${Fichier[@]}" > $2  # qui peut être le fichier source

exit 0

Encore merci !

Hors ligne

#8 Le 10/10/2011, à 14:53

Levi59

Re : Transformer des lignes automatiquement avec un script sh

Bien sûr, sans aucun problème! wink

Pense à éditer ton premier message et à ajouter [Résolu] dans le titre.

Hors ligne

#9 Le 14/10/2011, à 21:44

csm

Re : Transformer des lignes automatiquement avec un script sh

Bonsoir.

Je reviens avec une petite question sur ce script très pratique.

Imaginons que je souhaite que le script supprime toute une ligne contenant une chaîne de caractères particulière, disons ABCDEFG, la méthode est-elle la même ?

Enfin concernant les éléments substitués, comment en ajouter ? Imaginons que souhaite remplacer, en plus des modifications déjà apportées, tous les A par des Z ?

#!/bin/bash

while read
do
    REPLY=${REPLY//\"/}
    Fichier+=( "${REPLY//,/ & }" )
done < $1

printf '%s\\\\ \\hline\n' "${Fichier[@]}" > $2  # qui peut être le fichier source

exit 0

Cordialement et merci pour vos conseils avisés !

Hors ligne

#10 Le 14/10/2011, à 21:48

Haleth

Re : Transformer des lignes automatiquement avec un script sh

Brutalement, pour la recherche, tu peux utiliser grep
Pour le remplacement de char (A -> Z), y'a sed (j'ai peur de me faire taper dessus avec un bash que j'comprend po :'( )


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#11 Le 14/10/2011, à 22:26

Levi59

Re : Transformer des lignes automatiquement avec un script sh

csm a écrit :

Bonsoir.

Bonsoir! ^^

csm a écrit :

Imaginons que je souhaite que le script supprime toute une ligne contenant une chaîne de caractères particulière, disons ABCDEFG, la méthode est-elle la même ?

via le script bash si dessous, un simple test pour vérifier la présence du motif permettra d'ignorer les dites lignes (cf plus bas)

csm a écrit :

Enfin concernant les éléments substitués, comment en ajouter ? Imaginons que souhaite remplacer, en plus des modifications déjà apportées, tous les A par des Z ?

En bash (comme je l'ai fait dans le script) l'écriture est assez simple:
VAR=${VAR//MotifRecherché/NouveauMotif}
Si tu souhaites ne modifier que la première occurence, n'utilise qu'un slash:
VAR=${VAR/MotifRecherché/NouveauMotif}
ex ::

$ a=azerty
$ echo ${a/az/qw}
qwerty
$ a=aaazerty
$ echo ${a/a/q}
qaazerty
$ echo ${a//a/q}
qqqzerty
#!/bin/bash

while read
do
    ## si la ligne ne contient pas le motif reply on traite, sinon on ignore (disparait du fichier en sortie)
    [[ ! ${REPLY} =~ ABCDEFG ]] && {   
        REPLY=${REPLY//\"/}
        REPLY=${REPLY//MotifRecherché/NouveauMotif}
        Fichier+=( "${REPLY//,/ & }" ) 
    }
done < $1

printf '%s\\\\ \\hline\n' "${Fichier[@]}" > $2  # qui peut être le fichier source

exit 0

Hors ligne

#12 Le 14/10/2011, à 22:28

Haleth

Re : Transformer des lignes automatiquement avec un script sh

Pas mal !
Et niveau ressource, j'espere que c'est plus rapide qu'un sed oui ?


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#13 Le 14/10/2011, à 22:37

Levi59

Re : Transformer des lignes automatiquement avec un script sh

Pas vérifié mais comme je maitrise mal sed je ne saurais t'en dire plus.

Il faudrait lancer un sed équivalent avec time.

Hors ligne

#14 Le 15/10/2011, à 02:02

Postmortem

Re : Transformer des lignes automatiquement avec un script sh

Salut,

csm a écrit :

Imaginons que je souhaite que le script supprime toute une ligne contenant une chaîne de caractères particulière, disons ABCDEFG, la méthode est-elle la même ?

Avec sed :

sed -n '/ABCDEFG/! { s/"//g
s/,/ \& /g
s/a/z/g
s/$/\\\\ \\hline/
p }' fichiersource > fichiersortie

En rajoutant l'option -i à sed, on peut travailler directement dans le fichier source.

Haleth a écrit :

Et niveau ressource, j'espere que c'est plus rapide qu'un sed oui ?

Pas testé mais je pense que sed va plus vite sur de gros fichiers.


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#15 Le 15/10/2011, à 02:48

aduxas

Re : Transformer des lignes automatiquement avec un script sh

Postmortem a écrit :

Pas testé mais je pense que sed va plus vite sur de gros fichiers.

C'est sûr.  sed est d'une rapidité dingue.  Je l'utilise souvent avec des commandes compliquées sur des centaines de fichiers.  Ça prend des secondes.  sed est beaucoup plus rapide que pur bash.

Hors ligne