#1 Le 31/12/2018, à 14:44
- Brice Jeunieaux
grep : modifier un champ de ligne avec le numéro de la ligne
Bonjour / bonsoir ,
j'ai actuellement un fichier .csv contenant des lignes triées par ordre numérique, dans leurs premier champ. Voici une illustration :
l1;Champ2;FEE
l2;Champ2;FIE
l4;Champ2;FOE
l5;Champ2;FOO
Mon but est actuellement d'obtenir exactement cela :
l1;Champ2;FEE
l2;Champ2;FIE
l3;Champ2;FOE
l4;Champ2;FOO
La commande
grep -n '^l' csv.txt
me permettant d'obtenir le numéro d'une ligne, je souhaiterai "isoler" ce nombre et l'affecter au champ 1 de chaque ligne afin de retrouver une suite logique 1-2-3-4 au lieu de 1-2-4-5.
C'est là où je viens vers vous, car je n'arrive pas à réaliser cette affectation, donc en espérant qu'une fois de plus, on puisse éclairer ma lanterne sur ce sous-forum.
P.-S. : Mention spéciale au nom de mon fichier, "csv.txt". Décidément, on n'aura peut-être pas vu plus contradictoire...
Dernière modification par Brice Jeunieaux (Le 31/12/2018, à 15:07)
Hors ligne
#2 Le 31/12/2018, à 16:49
- Hizoka
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Salut,
while read line
do
((x++))
echo "l${x}; ${line#*;}"
done < csv.txt >> csv2.txt
devrait faire ce que tu demande en créant le fichier csv2.txt
Pense à réinitialiser x à 0 si tu fait des tests
Dernière modification par Hizoka (Le 31/12/2018, à 16:51)
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#3 Le 31/12/2018, à 17:32
- Brice Jeunieaux
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Salut,
while read line do ((x++)) echo "l${x}; ${line#*;}" done < csv.txt >> csv2.txt
devrait faire ce que tu demande en créant le fichier csv2.txt
Pense à réinitialiser x à 0 si tu fait des tests
Salut,
je ne comprends pas ce que tu veux que je fasse, par-là...
Je ne comprends pas l'utilité de read pour mes lignes dans le .csv, même en lisant bien le programme.
À aucun moment je ne dois les rentrer de cette manière à la main.
Disons que dans l'utilisation que je compte faire de ces lignes, l'utilisateur rentrera ses ligne de données champ par champ, et bien plus tard, quand tout sera stocké dans le .csv, il pourra effacer les lignes qu'il veut, et c'est là que mon besoin d'avoir des numéros de lignes ordonnés intervient, car mon programme qui affiche les entrées de mon .csv fait une boucle for pour lire les lignes de 1 à $nbLignes du coup, si la suite des x après le 'L' n'est pas régulière, il ne va pas afficher les lignes cassant la suite.
(Je raconte ça, mais si ça se trouve, l'explication ne t'aidera pas et c'est juste moi qui a mal compris ce que tu voulais me dire avec ton programme).
Hors ligne
#4 Le 31/12/2018, à 18:17
- diesel
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Si j'ai bien compris, tu veux remettre dans l'ordre le premier champ (en gros, tout ce qu'il y a avant le premier ";") et ne rien changer pour la suite (et pas l'ordre des lignes) ?
Si c'est ça, tu copies ce que t'a proposé Hizoka dans un fichier (toto.sh par exemple), tu lui fais un
chmod u+x toto.sh
puis
./toto.sh
et il ne te reste plus qu'à faire
mv csv2.txt csv.txt
Amicalement.
Jean-Marie
Dernière modification par diesel (Le 31/12/2018, à 18:23)
Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.
Hors ligne
#5 Le 31/12/2018, à 19:32
- Brice Jeunieaux
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Mmmh... Justement non, mon but n'est pas de "remettre dans l'ordre" le premier champ, dans le sens "intervertir des champs 1".
Il faut que si je supprime une ligne dont le champ un est "lx", il faudra que les lignes suivantes changent de valeur pour le premier champ (un peu comme dans une file d'attente où les patients décalent leur place, pour la métaphore).
Bien entendu, si vous préférez, le champ 1 peut ne pas avoir de "L", ça reste la même chose, il faut juste que si je prends tous les champs 1, j'ai une suite continue numérique.
Hors ligne
#6 Le 31/12/2018, à 20:07
- Watael
Re : grep : modifier un champ de ligne avec le numéro de la ligne
salut,
donc, on renumérote les lignes dans leur ordre d'apparition, c'est tout ?
cut -d';' -f 2- "$fichier" | nl -n ln -s ';' -w1
Dernière modification par Watael (Le 31/12/2018, à 20:08)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#7 Le 31/12/2018, à 20:15
- Brice Jeunieaux
Re : grep : modifier un champ de ligne avec le numéro de la ligne
salut,
donc, on renumérote les lignes dans leur ordre d'apparition, c'est tout ?
cut -d';' -f 2- "$fichier" | nl -n ln -s ';' -w1
Salut !
Ta réponse répond bien à mon problème... Après avoir lu "nl", j'ai découvert la commande "nl", mais j'ai du mal à comprendre ce que ta ligne de code fait exactement, "en interne"... EDIT : C'est bon j'ai compris les arguments de nl.
Sinon, nul doute qu'elle m'intéresse, en tripatouillant un peu je pourrais retrouver ma formulation correcte dans mon fichier.
Du coup, comment ta ligne de code fonctionne t-elle ? EDIT : N'y aurait-il pas, par contre, un moyen de concaténer le résultat en retour avec le L minuscule devant ? (C'est juste que dans le programme-mère, je les ai pris en compte, ça m'embêterais de tout rechanger... )
Dernière modification par Brice Jeunieaux (Le 31/12/2018, à 22:12)
Hors ligne
#8 Le 01/01/2019, à 02:28
- diesel
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Brice Jeunieaux, si tu veux qu'on te donne les bonnes réponses, il faudrait d'abord que tu l'exprime bien, ton problème.
relis ce que tu as demandé dans ton premier post et je t'assure que la réponse de Hizoka répond bien à la question posée.
D'ailleurs, la réponse de Watael fait juste la même chose en plus concis et en utilisant d'autres outils de linux.
Amicalement.
Jean-Marie
Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.
Hors ligne
#9 Le 01/01/2019, à 15:19
- Brice Jeunieaux
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Brice Jeunieaux, si tu veux qu'on te donne les bonnes réponses, il faudrait d'abord que tu l'exprime bien, ton problème.
relis ce que tu as demandé dans ton premier post et je t'assure que la réponse de Hizoka répond bien à la question posée.
D'ailleurs, la réponse de Watael fait juste la même chose en plus concis et en utilisant d'autres outils de linux.
Amicalement.
Jean-Marie
J'ai vu ce que son programme essayait de faire, mais comme je l'ai dit plus haut, pour la commande read, il ne faut surtout pas entrer les lignes manuellement, la mise en forme des lignes que je veux doit se faire automatiquement (soit le programme constate que les premiers champs ne forment plus une suite régulière, soit le programme le fait automatiquement dès que mon csv est édité au travers d'une interface), du coup je ne comprends pas et ne voit pas en quoi son programme répond à la problématique...
De plus, j'obtiens malheureusement une erreur. Voici mon programme dans lequel j'ai inséré son morceau de code :
#!/bin/bash
clear
cat table.txt
ecl1;Champ2;Champ3
l2;Champ2;Champ3
l4;Champ2;Champ3
l5;Champ2;Champ3
./test.sh: ligne 13: erreur de syntaxe près du symbole inattendu « done »
./test.sh: ligne 13: `done'
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
ho ""
x=0
while [ read line ] do
((x++))
echo "l${x}; ${line#*;}" >> csv2.txt
done
Et voici ce que le terminal me dit en sortie :
l1;Champ2;Champ3
l2;Champ2;Champ3
l4;Champ2;Champ3
l5;Champ2;Champ3
./test.sh: ligne 13: erreur de syntaxe près du symbole inattendu « done »
./test.sh: ligne 13: `done'
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
Il n'est pas censé y avoir d'erreur de syntaxe au niveau du while-do-done...
Dernière modification par Brice Jeunieaux (Le 01/01/2019, à 15:19)
Hors ligne
#10 Le 01/01/2019, à 15:26
- nany
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Bonjour,
c'est juste moi qui a mal compris ce que tu voulais me dire avec ton programme
Hors ligne
#11 Le 01/01/2019, à 19:50
- Nuliel
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Bonjour,
Je pense être pas loin d'une solution avec awk
awk -F ";" 'sub("^l[0-9]","l"NR,$1)' OFS=";" test
(il faut modifier un peu pour considérer les lignes qui sont après la 10ème, sinon je pense que ça fait ce qui est attendu)
Et avec sed j'ai essayé mais le = n'a pas voulu être remplacé par le numéro de ligne lorsqu'on substitue
sed s/^l[0-9]*/l=/ test
renvoie des = (donc ça marche pas)
Edit: je pense que
awk -F ";" 'sub("^l[0-9]*","l"NR,$1)' OFS=";" fichier
devrait fonctionner
Dernière modification par Nuliel (Le 01/01/2019, à 20:04)
Hors ligne
#12 Le 01/01/2019, à 20:04
- Watael
Re : grep : modifier un champ de ligne avec le numéro de la ligne
awk 'BEGIN{FS=OFS=";"}{gsub("^l[0-9]+","l"NR,$1)}1'
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#13 Le 01/01/2019, à 23:06
- Brice Jeunieaux
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Je vois que plusieurs propositions avec la commande awk sont venues accompagner les autres sur le sujet, mais voulant rester dans quelque chose de très simple et sans que j'aille à me torturer le cerveau, je pense que la première solution de Watael est la plus "rassurante" (message n°6).
Je l'ai donc bidouillé afin d'obtenir ça au final :
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
cat table.txt
l1;Champ2;Champ3
l2;Champ2;Champ3
l4;Champ2;Champ3
l5;Champ2;Champ3
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
cut -d';' -f 2- table.txt | nl -n ln -s ';' -w1
1;Champ2;Champ3
2;Champ2;Champ3
3;Champ2;Champ3
4;Champ2;Champ3
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
cut -d';' -f 2- table.txt | nl -n ln -s ';' -w1 | cut -d \; -f 1
1
2
3
4
[brice@brice-Lenovo-G505] [~/.../TestsCreationNvTable] $
La dernière commande tapée me donne donc ce que je voudrais obtenir après le 'L' minuscule du premier champ.
Y aurait-il donc une syntaxe très simple pour concaténer le 'L' minuscule, puis chaque chiffre, puis le reste de la ligne, dans une chaîne de caractères que je renvoie dans le fichier de base ?
J'ai vraiment, sans vouloir paraître non-collaboratif, du mal à comprendre ce que vous essayez de me dire avec la commande "read". Pourtant, je sais bien à quoi elle sert, mais je ne sais pas, il y a un blocage...
Hors ligne
#14 Le 01/01/2019, à 23:46
- Hizoka
Re : grep : modifier un champ de ligne avec le numéro de la ligne
Brice Jeunieaux, désolé mais j'ai rien pigé...
je pensais avoir répondu à ta question et je ne pige ton post #9 qui ne reprend pas ce que j'ai fait...
comme je ne comprends pas : À aucun moment je ne dois les rentrer de cette manière à la main.
Enfin bon, le principal c'est que les autres propositions aient fonctionné.
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#15 Le 02/01/2019, à 00:02
- Zakhar
Re : grep : modifier un champ de ligne avec le numéro de la ligne
J'ai vraiment, sans vouloir paraître non-collaboratif, du mal à comprendre ce que vous essayez de me dire avec la commande "read". Pourtant, je sais bien à quoi elle sert, mais je ne sais pas, il y a un blocage...
La commande "read" ne veut pas dire (nécessairement) que tu demandes des entrées à l'utilisateur, comme tes messages laissent croire que tu l'a compris (ou alors on se comprend mal !)
La commande "read", dans ce qui t'était proposé, est assortie d'une redirection qui va simplement lire ton fichier d'entrée, et l'utilisateur n'a absolument rien à entrer au clavier.
C'est parfois la seule issue d'utiliser cela lorsqu'on n'a pas sous la main des petits programmes comme "nl" qui font ce qu'on veut, parce que "read" va lire les lignes 1 par 1 du fichier en entrée, et ensuite ton programme, dans la boucle de "read", fait absolument ce qu'il veut. On peut alors coder des algorithmes aussi compliqués qu'on veut selon la succession de lignes. Et c'est bien sûr bien moins performant qu'un programme, parce que c'est du shell interprété ligne à ligne !
Pour en revenir à rajouter un "L" en début de ligne, c'est on ne peut plus simple, tu "pipe" le résultat avec un sed 's/^/l/', et ça ajoutera un 'L' minuscule à chaque début de ligne.
Exemple :
$ head test
12 aaaa
13 bbbb
14 cccc
$ head test | sed 's/^/l/'
l12 aaaa
l13 bbbb
l14 cccc
Dernière modification par Zakhar (Le 02/01/2019, à 00:07)
"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)
Hors ligne