ça, ça va être difficile maintenant, car certains cartons contiennent bien plus que 4 articles :/Envoyé par bricko
Ne prends que le sed alors.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 $ sed 's/.\{1\}\(.\{15\}\)\(.\{6\}\).*/\2 \1/' umf-aus-trs_advice_J72.txt 89097 12345678015 89097 12345678025 89097 123456789010015 47233 123456789010015 58474 123456789010013 47233 445566015 47233 445566025 47233 445566035 47233 445566045 47233 445566055 47233 445566065 47233 445566075 47233 445566085 47233 445566095 47233 445566105 26967 12345678036 23456 12345678041 98218 123456789010026 70958 123456789010023 23456 123456789010021 28034 12345678055 86200 123456789010036 68530 123456789010043 68530 123456789010043 54809 123456789010058 54809 123456789010058 68530 12345678063 68530 12345678073 54809 12345678088 54809 12345678098
Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.
Effectivement,
Je m'en suis rendu compte.
Mais déjà, j'aimerais découper en colonnes mon fichier comme je l'ai déjà indiqué
$1 -> colonne1
$2-16 -> colonne2
$17-22 -> colonne3
puis le reste est déjà en colonne.
Je sais que je suis pas très bon en explication.
@Flodelarab je n'ai pas toutes les colonnes avec ton sed
Mais non le reste n'est pas en colonne. Tu ne t'es pas rendu compte que tu avais "2023", et à la ligne du dessous "22 4".
Fichier pourri.
Méthode pourrie.
Énoncé pourri.
Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.
Oui mais dans tous les cas c'est pas grave.
Les informations les plus importantes se trouvent dans les 2 et 3ème colonne.
L'objectif c'est d'avoir ces deux informations assez claires mais de garder toute de même le reste de la ligne.
J'ai les mêmes résultats.
Pour mieux comprendre:
Code : Sélectionner tout - Visualiser dans une fenêtre à part man cut
Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.
@Flodelarab en fait avec ton sed ça marchait très bien.
Mais serait-il possible de récupérer toute une ligne par exemple la première:
Le découpage que t'avais est correcte. Mais comment faire pour récupérer toute la ligne avec ton découpage.
Code : Sélectionner tout - Visualiser dans une fenêtre à part 4 1234567801 589097 32 0 0 25 4 4935232014070914070958 0 2 0 0 0 0.00000000000341392324000000000341395276
Si ce n'est que ça, alors peut-être suffit-il d'ajouter un \3 comme ceci (non testé):
@Flodelarab: Pourquoi .\{1\} plutôt que juste . ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part sed 's/.\{1\}\(.\{15\}\)\(.\{6\}\)\(.*\)/\2 \1 \3/' umf-aus-trs_advice_J72.txt
Je n'ai toujours pas très bien compris... il faut juste permuter les 2 premiers champs?
Je vais le tester
En fait j'aimerais comprendre la construction de ce sed, il m'a l'air assez compliqué.
Un petit éclaircissement
s: substitutionsed 's/.\{1\}\(.\{15\}\)\(.\{6\}\).*/\2 \1/' umf-aus-trs_advice_J72.txt
s/toto/tata/: substitution de toto par tata
. :n'importe quel caractère
.\{73\} :n'importe quel caractère répété 73 fois
\( \): groupe
\1: référence arrière du premier groupe
\2: référence arrière du second groupe
etc...
s/\(blablabla\)\(blobloblo\)\(bliblibli\)/\2\3\1/ :substitution donnant "blobloblobliblibliblablabla"
.* :n'importe quel caractère répété en n'importe quelle quantité (même 0)
A toi de trouver la formulation qui t'agrée.
Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.
.\{1\} c'est un caractère (quelconque)
.\{15\} c'est 15 caractères. Il est entre parenthèses pour pouvoir le référencer en tant que \1 (à droite)
.\{6\} c'est 6 caractères. Il est entre parenthèses pour pouvoir le référencer en tant que \2 (à droite)
" " c'est une espace (à vérifier s'il est bien utile)
.* c'est le reste des caractères. Il est entre parenthèses pour pouvoir le référencer en tant que \3 (à droite)
[edit]Grillé! Y en a qui tapent plus vite que leur ombre...[/edit]
Ton sed marche très bien j'ai pu récupérer toutes mes lignes.
J'aurais une question, j'aimerais adapter le nouveau fichier au code de @sve@r
Le numéro de carton se trouvant de la position 8 à la position 22.
Le code est ainsi
Pour chaque ligne, nous avons un numéro de carton qui commence de la ligne 8 à la ligne 22.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
45
46
47
48
49
50
51
52 fonction qui extrait une partie de l'info split() { echo "$1" |cut -f$2 -d: } # Effacement des anciens fichiers rm -f ? # Traitement des datas fich=1 nb_lig=0 cat inputter.txt| while read info do # Si le numero de carton a changé carton=$(split "$info" 2) if test "$carton" != "$mem_carton" then # On a un nouveau carton mem_carton="$carton" # S'il y a des précédentes données Ã* écrire on les écrit dans le fichier if test "${#buffer[*]}" -gt 0 then for lig in "${buffer[@]}" do echo "$lig" done >>"$fich" fi # On mémorise le nb de lignes écrites nb_lig=$(expr $nb_lig + ${#buffer[*]}) # Le buffer est réinitialisé pour le nouveau carton buffer=() fi # Ajout des données dans le buffer des datas Ã* écrire buffer[${#buffer[*]}]="$(split "$info" 1) $carton" # Si les données dépassent la taille de 4 if test $(expr ${#buffer[*]} + $nb_lig) -gt 4 then # On a un nouveau fichier fich=$(expr $fich + 1) nb_lig=0 fi done
Bien évidement nous avons des lignes pour lesquelles nous avons un blanc à la position 8-12 voir 8-14.
Mais bien évidemment ces numéros même courts reste des numéros cartons.
Encore une fois merci pour votre aide.
Bonjour,
Je reviens vers vous par rapport à mon problème.
J'ai par exemple
Le problème que j'ai pour l'instant c'est de pouvoir récupérer l'élément de la 2ème colonne et ainsi de pouvoir la comparer à l'élément de la 2ème colonne de la 2ème ligne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 589097 1234567801 32 0 0 25 4 4935232014070914070958 0 2 0 0 0 0.00000000000341392324000000000341395276 589097 1234567802 32 0 0 25 4 4935232014070914070958 0 2 0 0 0 0.00000000000341392324000000000341395276 589097 12345678901001 32 0 0 10 4 4935232014070914070958 0 10 0 0 0 0.00000000000341392324000000000341395276 547233 12345678901001 34 0 0 10 4 4935232014070914070958 0 10 0 0 0 0.00000000000001074106000000000003392014 358474 12345678901001 32 0 0 5 4 4935232014070914070958 0 10 0 0 0 0.00000000000204811406000000000204817557
la fonction que @sve@r est ainsi:
Puis la suite du code me permet de processer de la sorte:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 split() { echo "$1" |cut -f$2 -d/ }
Ainsi je devrais avoir 2 fichiers: un contenant les 2 premières lignes et l'autre comprenant le 3 dernières colonnes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
45 rm -f ? # Processing Data fich=1 nb_lig=0 #for info in "${data[@]}" cat inputter.txt| while read info do # If the Carton Number has change carton=$(split "$info" 2) if test "$carton" != "$same_carton" then # We have a new carton Number same_carton="$carton" # If we have previous lines in the buffer we wrote down in the file if test "${#buffer[*]}" -gt 0 then for lig in "${buffer[@]}" do echo "$lig" done >>"$fich" fi # we retain lines from the buffer nb_lig=$(expr $nb_lig + ${#buffer[*]}) # we initiate the buffer() buffer=() fi # we add lines to the buffer table buffer[${#buffer[*]}]="$(split "$info" 1) $carton" # if the data is beyond 4 lines if test $(expr ${#buffer[*]} + $nb_lig) -gt 4 then # we have a new file fich=$(expr $fich + 1) nb_lig=0 fi done
Pour l'instant j'ai 3 fichiers. J'ai l'impression que le problème réside dans la fonction split(). Je ne récupère pas très bien le Numéro de carton et ainsi faire la comparaison.
Merci pour votre aide.
Pour la dernière fois, si tu veux faire de la manipulation de fichiers texte, il faut que tu t'inities à grep, sed, awk.
Vouloir réinventer la roue par un script est une grosse erreur (en temps, en incompréhension, en bugs...)
Comme ton fichier est organisé en colonnes (et devenu propre), je te conseille: awk
Voici un bon document de référence sur awk que tu dois lire.
Le deuxième champ sera alors simplement désigné par $2
Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.
Flodelarab a raison mais je vais détailler un peu plus
Le shell est un outil dédié à la manipulation des programmes externes. En effet, quand tu veux récupérer le résultat d'une action, te suffit simplement d'appeler l'action au travers de l'appel interne $(...).
Exemple: récupérer l'action du calcul 2+3 => res=$(expr 2 + 3) (tombé en désuétude depuis le bash qui autorise res=$((2+3)) mais ce mécanisme peut être adapté à tout autre besoin que le bash ne sait pas faire).
De plus, Unix/Linux a été créé selon un principe pour l'époque révolutionnaire: avoir sa configuration toute entière basée sur des fichiers textes. La gestion des utilisateurs ? Un fichier texte /etc/passwd (plus éventuellement un autre /etc/group). Le réseau ? Un fichier texte /etc/network/interfaces.
Le but était de pouvoir accéder et modifier facilement la config (si je veux créer un nouvel user je peux le faire avec un simple éditeur si je veux).
Partant de là, Unix/Linux possède un paquet d'outils dédiés à la manipulation des fichiers textes. T'as grep qui permet d'extraire des lignes, cut qui pemet de les couper verticalement, split qui te les coupe horizontalement, paste qui peut les joindre, sed qui peut les modifier selon certains modèles, tr qui peut les modifier selon d'autres modèles, et le fameux awk, outil complet qui permet carrément de programmer un algo de traitement (avec des boucles, des conditions, etc) qui s'appliquera à chaque ligne traitée.
Et donc 1) puisque tous ces outils existent et permettent de faire danser tes fichiers textes comme des caniches pour le susucre ; et 2) puisque le shell a accès facilement à tous ces outils ; il devient évident que le shell n'a plus rien à créer.
Toi, tout ce que tu as à faire, c'est apprendre à utiliser ces outils pour pouvoir ensuite faire ce que tu veux avec tes fichiers. Mais cette phase d'apprentissage est peut-être minime mais obligatoire !!!
Pas tout à fait quand-même. Le script offre quand-même des outils d'algorithmique (boucles, conditions, mémoires) qui permettent (en appelant les outils de traitement adéquats et en mémorisant leurs résultats pour les réutiliser) de résoudres des problèmes un peu complexes...
Mouais. C'est aussi mon impression...
Cette fonction permet de récupérer la nième colonne d'une ligne où le séparateur est connu et fixe (ici un slash => -d/).
Elle peut-être adaptée à n'importe quel format pourvu qu'il soit similaire (par exemple séparateur deux-points => -d:). Si le séparateur est une tabulation alors pas la peine de le préciser car c'est le séparateur par défaut de cut.
Donc on passe à la fonction la ligne entière, et la colonne voulue et on récupère sa valeur en retour.
Maintenant si en plus le format change et que le champ X de la ligne Y ne correspond pas au champ X de la ligne Y+1 (par exemple parce qu'il y a des tabulations en plus pour aligner le fichier à l'écran) là cut ne peut plus rien faire (il lui faut impérativement des lignes calées à l'identique) et donc comme le dit Flodelarab, awk sera plus adapté (lui il sait enlever les espaces inutiles). Personnellement j'aime bien awk mais comme il est très puissant (et donc ipso-facto très lourd à appeler) je ne l'utilise qu'en toute dernière extrémité. Mais s'il le faut alors il le faut.
Un exemple de la même fonction avec awk (séparateur slash)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 split() { echo "$1" |awk -F/ -vfield=$2 '{printf("%s\n", $field)}' }
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Merci a vous tous ,
je pense avoir réussi à me débrouiller avec tout ce que vous avez dit .
Je mettrais la réponse Mardi, je suis en long week-end.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager