tu vois, à ne pas vouloir optimiser :lol:Citation:
Je ne suis pas très fier de cette solution
manquerait plus que tu donnes des solutions en toc :aie:Citation:
mais ça fait le job
:mouarf:
Version imprimable
tu vois, à ne pas vouloir optimiser :lol:Citation:
Je ne suis pas très fier de cette solution
manquerait plus que tu donnes des solutions en toc :aie:Citation:
mais ça fait le job
:mouarf:
Merci beaucoup pour votre aide!
Je marque officiellement à Résolu cette discussion.
J'aurais juste une dernière question, comment faire si mon input est un fichier avec le code de @Sve@r.
Un fichier avec unpour une ligne.Code:<article> <n°colis>
Merci encore une fois.
Tu remplaces for info in "${data[@]}" par cat fichier_input |while read info et c'est tout.
Sinon il y a une seconde écriture en remplaçant
parCode:
1
2
3
4 for info in "${data[@]}" do ... (tout le code)... done
Code:
1
2
3
4 while read info do ... (tout le code)... done <fichier_input
L'avantage de la première écriture, c'est que tu peux traiter absolument n'importe quel flux entrant pourvu que celui-ci t'affiche des lignes (find, ping, grep). Si par exemple la liste articles/cartons est créée par un programme (exemple) "megacreator" (et que ce programme se contente de créer la liste à l'écran) ben te suffit d'écrire megacreator |while read info....
L'inconvénient c'est que toute variable créée dans le while est perdue au done. Je fais l'hypothèse que c'est à cause de l'indépendance des deux processus mais bizarrement, ça ne le fait pas en ksh (les variables crées restent connues). Et j'ai jamais compris pourquoi.
L'avantage de la seconde écriture c'est qu'il n'y a pas de pipe donc tu conserves tes variables si t'as besoin. Mais tu ne peux pas traiter de commande (sauf en bash en écrivant de cette façon: while read ligne; do ... done <<< "$(commande)").
Encore une fois merci.
Je pense que j'ai pris gout à ce langage et que je vais m'y mettre très sérieusement.
Merci à la communauté du site.
le pipe s'exécute dans une sous-interpréteur (à l'instar des substitutions de commandes : echo $(var=foo); echo "${var:-vide}").Citation:
Je fais l'hypothèse que c'est à cause de l'indépendance des deux processus mais bizarrement, ça ne le fait pas en ksh (les variables crées restent connues). Et j'ai jamais compris pourquoi.
il me semble me souvenir que certains ksh ont encore ce même comportement.
"récemment", une option du shell a été ajoutée à bash, pour que les variables créées dans la partie droite du pipe soient accessibles dans le reste du script (cf. man bash /lastpipe).
aïe, mes yeux : ça brûle!Citation:
L'avantage de la seconde écriture c'est qu'il n'y a pas de pipe donc tu conserves tes variables si t'as besoin. Mais tu ne peux pas traiter de commande (sauf en bash en écrivant de cette façon: while read ligne; do ... done <<< "$(commande)").
:mouarf:cf. man bash /Substitution de procesusCode:
1
2
3
4 while read -r v1 v2 do : ... done < <(commande)
Je reviens vers vous car cette fois-ci je le véritable jeu de données.
Mon numéro de carton va du caractère 2-15 et mon numéro d'article va de 16-24.
Comment adapter mon code pour un peu dire découper mon fichier en plusieurs.
Merci d'avance
Le fichier est en pièce jointe
La première chose qui saute aux yeux, c'est que chaque ligne n'a pas le même nombre de champs.
La deuxième chose est que les infos que tu donnes sur les positions à extraire ne fonctionnent pas avec le fichier txt transmis.
Enfin, je filtrerais ce fichier avec un sed avant de l'envoyer au pipe déjà évoqué.
Code:
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 $ sed '1d;$d;s/.\(.\{14\}\)\(.\{9\}\).*/\1 \2/' umf-aus-trs_advice_J7.txt 1234567801 589097 32 1234567802 589097 32 12345678901001 589097 32 12345678901001 547233 34 12345678901001 358474 32 44556601 547233 34 44556602 547233 34 44556603 547233 34 44556604 547233 34 44556605 547233 34 44556606 547233 34 44556607 547233 34 44556608 547233 34 44556609 547233 34 44556610 547233 34 1234567803 626967 32 1234567804 123456 99 12345678901002 698218 44 12345678901002 370958 32 12345678901002 123456 10 1234567805 528034 30 12345678901003 686200 36 12345678901004 368530 34 12345678901004 368530 36 12345678901005 854809 32 12345678901005 854809 34 1234567806 368530 38 1234567807 368530 40 1234567808 854809 36 1234567809 854809 38 $
Bonjour,
je n'ai pas compris ce que tu voulais dire par le pipe déjà évoqué
puis c'est vrai qu'il y a des blancs au début mais il faut les prendre en compte.
Les positions sont correctes en fait.
Oui je viens de comprendre ce que tu veux dire.
Effectivement, chaque ligne n'a pas le même nombre de champ.
je devrais rajouter de zéros dans le cas ou ma première colonne n'a pas 14 caractères (ou digits)
comment faire pour avoir le reste des champs avec ta commande sed.
Merci
pour être tout à fait clair, à partir du dernier fichier en pièce jointe, quelles sont les informations à prendre en compte ?
par exemple :Code:4 1234567801589097 32 0 0 25 4 4935232014070914070958 0 2 0 0 0 0.00000000000341392324000000000341395276
???Code:12345678015 97
Bonjour,
les informations à prendre en compte sont le 14 premiers caractères (ou digits) qui sont le NumCarton
Puis les 5 caractères suivants qui sont le NumArticles.
Sauf que pour certaines lignes, la première colonnes est reduite:
Dans tous les cas les caractères de 2-16 correspondent au NumCartonCode:
1
2 44556601 547233 34
De 16-22 -> NumArticle.
Je dois découper ainsi mon fichier
Mais comment faire pour récupérer avec mon sed toutes les champs de ma lignes?
J'ai fait l'hypothèse que le numéro d'article de 14 caractères commençait à la position 37 et que le numéro de carton de 9 caractères commençait à la suite.
Voilà le résultat.
Évidemment, ça dépasse 4.Code:
1
2
3
4
5
6
7 $ rm -f file_cartons*; sed 's/.\{36\}\(.\{14\}\)\(.\{9\}\).*/\1 \2/' umf-aus-trs_advice_J72.txt |awk '(NR==1){next;} (a[$2]==0){printf "\n"} {a[$2]++; printf " "$0;}' |awk 'NR==1{next;} {if (e+NF<9) {e=e+NF;carton=carton$0;} else {num++;print carton>"file_cartons"num".txt";carton=$0;e=NF} } END{num++;print carton>"file_cartons"num".txt";}';grep [0-9] file_cartons* file_cartons1.txt: 4935232014070 914070958 4935232014070 914070958 4935232014070 914070958 4935232014070 914070958 file_cartons2.txt: 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 4935232014071 314071358 file_cartons3.txt: 4935232014071 214071258 file_cartons4.txt: 4935202014071 414071458 4935202014071 414071458 4935202014071 414071458 4935202014071 414071458 file_cartons5.txt: 4935232014071 514071558 4935232014071 514071558 file_cartons6.txt: 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658 4935232014071 614071658
On aura ptêt le vrai énoncé dans 50 messages.
[edit]Au temps pour moi: post croisé avec celui ci-dessus. Qui dit encore n'importe quoi:
Le caractère 16 est commun au carton et à l'article?
Ya des espaces en plein milieu du numéro?[/edit]
Code:
1
2
3
4
5
6
7
8
9
10 cut --output-delimiter=$'\t' -c2-15,16-22 fichier_bis.txt 1234567801 589097 1234567802 589097 12345678901001 589097 12345678901001 547233 12345678901001 358474 44556601 547233 44556602 547233 44556603 547233 ...
Après casse-tête, j'arrive à qqch de censé:
Code:
1
2
3
4
5
6
7
8
9
10
11 $ rm -f file_cartons*; sed 's/.\{1\}\(.\{14\}\)\(.\{7\}\).*/\2 \1/' umf-aus-trs_advice_J72.txt |awk '(a[$2]==0){printf "\n"} {a[$2]++; printf " "$0;}' |awk 'NR==1{next;} {if (e+NF<9) {e=e+NF;carton=carton$0;} else {num++;print carton>"file_cartons"num".txt";carton=$0;e=NF} } END{num++;print carton>"file_cartons"num".txt";}';grep [0-9] file_cartons* file_cartons1.txt: 589097 1234567801 589097 1234567802 file_cartons2.txt: 589097 12345678901001 547233 12345678901001 358474 12345678901001 547233 44556601 file_cartons3.txt: 547233 44556602 547233 44556603 547233 44556604 547233 44556605 file_cartons4.txt: 547233 44556606 547233 44556607 547233 44556608 547233 44556609 file_cartons5.txt: 547233 44556610 626967 1234567803 123456 1234567804 file_cartons6.txt: 698218 12345678901002 370958 12345678901002 123456 12345678901002 528034 1234567805 file_cartons7.txt: 686200 12345678901003 368530 12345678901004 368530 12345678901004 file_cartons8.txt: 854809 12345678901005 854809 12345678901005 368530 1234567806 368530 1234567807 file_cartons9.txt: 854809 1234567808 854809 1234567809
Je ne comprends pas ton dernier post.
Puis ton premier sed était très bien c'est juste que je n'avais pas tous les champs.
Comment faire pour avoir tous les champs.
pour afficher tous les champs, il faudrait qu'on connaisse le format en taille fixe du ficher.
Dans la première partie de la discussion, nous avons cherché à répartir les lignes d'un fichier contenant 2 colonnes (nomArticle, numCarton) dans des fichiers ne dépassant pas 4 éléments mais les remplissant au max.Citation:
Je ne comprends pas ton dernier post.
Dans cette deuxième partie de discussion, nous avons les valeurs réelles.
J'extrais donc le nom de l'article (caractère 16 à 22) et le num du carton (2 à 15).
Puis je répartis dans les fichiers comme nous avions conclu la première partie.
Effectivement, le résultat fonctionne par groupe de 4. Voilà pourquoi je dis que le résultat est censé.
Le premier nombre est l'article
Le second est le numcarton.
Le troisième est l'article.
Le quatrième est le num carton, etc...
ci-joint le fichier final.
J'ai 2-16 -> le NumCarton
17-22 -> le NumArt
C'est vrai que j'ai des blancs parfois pour certaines lignes le NumCarton.
Mais il faut que je les prenne en compte.
Merci pour votre aide.
Avec ces précisions:
Code:
1
2
3
4
5
6
7
8
9 $ rm -f file_cartons*; sed 's/.\{1\}\(.\{15\}\)\(.\{6\}\).*/\2 \1/' umf-aus-trs_advice_J72.txt |awk '(a[$2]==0){printf "\n"} {a[$2]++; printf " "$0;}' |awk 'NR==1{next;} {if (e+NF<9) {e=e+NF;carton=carton$0;} else {num++;print carton>"file_cartons"num".txt";carton=$0;e=NF} } END{num++;print carton>"file_cartons"num".txt";}';grep [0-9] file_cartons* file_cartons1.txt: 89097 12345678015 89097 12345678025 89097 123456789010015 47233 123456789010015 file_cartons2.txt: 58474 123456789010013 47233 445566015 47233 445566025 47233 445566035 file_cartons3.txt: 47233 445566045 47233 445566055 47233 445566065 47233 445566075 file_cartons4.txt: 47233 445566085 47233 445566095 47233 445566105 26967 12345678036 file_cartons5.txt: 23456 12345678041 98218 123456789010026 70958 123456789010023 23456 123456789010021 file_cartons6.txt: 28034 12345678055 86200 123456789010036 68530 123456789010043 68530 123456789010043 file_cartons7.txt: 54809 123456789010058 54809 123456789010058 68530 12345678063 68530 12345678073 file_cartons8.txt: 54809 12345678088 54809 12345678098
en fait pourquoi ne pas reprendre mon fichier et le sequencé comme vous faîtes et le mettre dans un seul fichier.
Avec le fichier créer je pourrais le reprendre avec l'algo de @sve@r