Pas d'erreurs chez moi. Pourrais-tu poster le code (m)awk que tu exécutes?
Version imprimable
Je te recopie le code
J'ai vérifié que mes espaces n'avaient pas été fait avec la touche Alt Gr.Code:
1
2
3
4
5
6
7
8 chemin='/home/francois/Desktop/test.csv' nouveaufichier='/home/francois/Desktop/temp' > $nouveaufichier awk 'Begin{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx" print > "$nouveaufichier"}' "$chemin"
Ah ok., si tu mets tout sur une ligne, tu dois effectivement mettre un ; pour terminer la structure for() avant le print de l'instruction suivante.
Sur plusieurs lignes comme dans mon post plus haut, la fin de ligne termine l'instruction.
Essaye d'abord en dirigant le print vers la console:
Si le résultat te convient, dirige le print vers un fichier.Code:awk 'BEGIN{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx"; print}' fichier_test
Code:awk 'BEGIN{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx"; print > "fichier_out"}' fichier_test
décidément quand çà veut pas...
J'ai testé la 1ere ligne, elle ne modifie rien ! aucun champ vide ne se remplit :(
par contre je n'ai plus d'erreur !
en fait les champs vide ne semblent pas être pris en compte avec printf,
maintenant que j'ai un shell sous la main
voici une solution possible (basée sur la version bash)
Ce qui donneCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #!/bin/bash No_champs=( 2 3 ) # soit les n° des champs souhaités moins un : les arrays commencent à 0 echo "aa;bb;;;" > fichier.csv echo "aa;bb;;dd" >> fichier.csv echo "aa;bb;cc;;" >> fichier.csv echo ";;;;" >> fichier.csv echo ";;" >> fichier.csv echo ";;;d;z" >> fichier.csv > fichiercible.csv while read ligne do IFS=";" read -a Champs <<< "$ligne" ##echo "Ligne lue ${Champs[*]}" taille=${#Champs[*]} ##echo "Taille de la ligne $taille" for indice in ${No_champs[@]} do ## Evite d'insérer des élément quand ils sont non existant à l'origine if [ $indice -le $taille ] then test -z ${Champs[indice]} && Champs[indice]="xx" fi done ## Comparé a printf cela permet de prendre en compte les champs ## vide du tableau qui n'apparaissait pas avec printf. for indice in "${!Champs[@]}" do if [ $indice -eq 0 ] then var="${Champs[$indice]}" else var="$var;${Champs[$indice]}" fi done echo "$var" >> fichiercible.csv done < fichier.csv
Citation:
Test fichier format unix
1,6c1,6
< aa;bb;;;
< aa;bb;;dd
< aa;bb;cc;;
< ;;;;
< ;;
< ;;;d;z
---
> aa;bb;xx;xx
> aa;bb;xx;dd
> aa;bb;cc;xx
> ;;xx;xx
> ;;xx
> ;;xx;d;z
Test fichier format Dos
1,6c1,6
< aa;bb;;;
< aa;bb;;dd
< aa;bb;cc;;
< ;;;;
< ;;
< ;;;d;z
---
> aa;bb;xx;xx;
> aa;bb;xx;dd
> aa;bb;cc;xx;
> ;;xx;xx;
> ;;
;xx
> ;;xx;d;z
OK merci jabbounet. le code marche tres bien ! Je vais essayer de comprendre le script ! encore merci :ccool:
Maintenant j'aimerai qd même comprendre pourquoi le script awk ne fonctionne pas !
j'utilise rarement awk même s'il est très puissant mes connaissances le concernant sont très limités.
pour les trucs compliqué sur les fichiers texte j'utilise perl en général.
J'avoue que je ne connais pas trop pearl.
Le script que je suis en train de réaliser va lancer des scripts en pearl déjà fait pour certaines parties de la procédure que j'automatise.
J'ai essayé de faire un script global mais vu qu'ils ne sont pas commentés... Ils sont illisible pour moi, même avec un book et internet.
En tout cas je te remercie pour ton (votre) aide !
bon j'ai regardé ton script jabbounet et il a certaine chose que je ne comprends pas.
Je ne comprends pas ces commandes :
"<<<" je ne connais que << et < respectivement utilise l'entrée standard comme flux et utilise un fichier comme entrée standard
Le "#" dans taille=${#Champs[*]}, pour moi # permettait de faire des commentaires...
[Je viens de trouver, à priori çà renvois la valeur du nb total de champs]
Je suppose que le "*" signifie que l'on appelle l'ensemble du tableau.
Le "@" dans No_champs[@] correspond à l'ensemble des valeurs ? (on pourrait le remplacer par No_champ[ 2 3 ].
<<< c'est en quelque sorte un "mini here-doc". très pratique pour éviter des formes lourdes telles que :quant au # dans les variables et tableaux, mais tu as déjà compris :Code:
1
2
3
4
5 echo "tra la lère" | commande ... # on fait l'économie d'une commande(?) commande ... <<< "tra la lère" # ça fonctionne avec les variables commande ... <<<"$var"
Code:
1
2
3
4
5
6 var="tra la lère" echo ${#var} 11 var=(tra la lère) echo ${#var[@]} 3
pas mal de réponse concernant la manipulation des tableaux en bash ici
http://tldp.org/LDP/abs/html/arrays.html
Bon j'ai un prob avec ton script jabbounet. Il me tronque les champs supérieur au champ max contenu dans No_Champ. Ce que je ne comprends pas car je pensais que ce bout de code lisait tous les indices sauf ceux modifiés...
Il faudrait peut être que je fasse une boucle while qui lise tout les indices en utilisant $taille comme limitateur ?Code:
1
2 for indice in "${!Champs[@]}"
Merci pour le lien ;)
J'avais trouvé ici http://www.trustonme.net/didactels/148.html et http://www.epons.org/shell-bash-variables.php
Par contre, je ne trouve pas concernant "<<<"
ici tu as la réponse:
http://www.gnu.org/software/bash/man...redirection-98
Citation:
3.6.6 Here Documents
This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command.
The format of here-documents is:
No parameter expansion, command substitution, arithmetic expansion, or filename expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ‘`’.Code:
1
2
3
4 <<[−]word here-document delimiter
If the redirection operator is ‘<<-’, then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.
3.6.7 Here Strings
A variant of here documents, the format is:
The word is expanded and supplied to the command on its standard input.Code:
1
2<<< word
Désolé je n'avais pas vu le message de N_BaH
ok Merci pour les infos :ccool:
Ça m'a échappé mais tu as fait 2 autres erreurs de retranscription de mon code. A nouveau, si tu mets plusieurs lignes de code awk sur une seule, tu dois terminer chaque instruction par un ;. Regarde à nouveau mon exemple ici:
http://www.developpez.net/forums/m4603577-12/
De plus, en remettant sur une seule ligne tu as oublié un élément essentiel dans la condition ternaire, c'est l'affectation du résultat de <cond>?<valeur si vrai>:<valeur si faux> au champ $n.
Si on remet ça sur une seule ligne, ça doit donner ceci:
Ou bien tu reprends mon code sur plusieurs lignes dans mon post plus haut. Je te le recommande d'ailleurs, pour des raisons de lisibilité. Les one-liner, ça fait bien dans un forum mais après, quand il faut se relire... ;)Code:awk 'BEGIN{FS=OFS=";";split("3-4", p, "-")} {for (i in p) $p[i]=$p[i]?$p[i]:"xx";print}' fichier.test
Testé sur un fichier.test:
Code:
1
2
3
4 $ cat fichier.test aa;bb;;; aa;bb;;dd aa;bb;cc;;
ripat :
Ton script fonctionne parfaitement chez moi.
(Il faut vraiment que je regle ce prob d'internet sur ma machine virtuelle pour faire des copier/coller et que j'aille voir l'ophtalmo pour mes yeux 8O).