Traitement fichier CSV avec "sed"
Résolu/Fermé
yann747
Messages postés
128
Date d'inscription
mardi 25 octobre 2011
Statut
Membre
Dernière intervention
13 octobre 2021
-
2 janv. 2012 à 21:20
yann747 - 4 janv. 2012 à 15:52
yann747 - 4 janv. 2012 à 15:52
A voir également:
- Sed csv
- Remplacez le mot sed par le mot mais dans tout le texte. combien de caractères contient le document suite à cette modification (en incluant les espaces) ? ✓ - Forum Shell
- Convertir vcf en csv - Télécharger - Gestion de données
- Sed crlf - Astuces et Solutions
- Csv converter - Télécharger - Bases de données
- Convertir csv en pst - Forum Bureautique
8 réponses
Utilisateur anonyme
3 janv. 2012 à 12:11
3 janv. 2012 à 12:11
salut,
J'utiliserais plutôt awk
J'utiliserais plutôt awk
awk -F';' '{ gsub("\"","") gsub("##","-") n = split($2,a,"\\|\\|") for(i=1; i<=n; i++){ if(i%3){ f = (f ? f";\""a[i]"\"" : "\""a[i]"\"") }else{ print "\""$1"\";"f";\""a[i]"\""; f = "" } } }' filmografictiveparce que ça va être pénible de retenir le premier champ, et de le rajouter quand il faut en sed.
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 407
Modifié par zipe31 le 3/01/2012 à 14:33
Modifié par zipe31 le 3/01/2012 à 14:33
Salut,
;-))
Zen my nuggets ;-)
Faites un geste pour l'environnement, fermez vos fenêtres et adoptez un manchot.
$ cat film.txt "Martin Scorsese";"Mad Max||1979||Action||Raging Bull||1980##1981||Drame||Cannonball||1975||Action##Comédie##Drame" $ cat format.sed s/;/\n/4 s/\([^;]*;\)\(.*\n\)\(.*\)/\1\2\1\3/ P D $ cat pre-format.sed s/||/";"/g s/##/-/g $ sed -f format.sed < <(sed -f pre-format.sed film.txt) "Martin Scorsese";"Mad Max";"1979";"Action" "Martin Scorsese";"Raging Bull";"1980-1981";"Drame" "Martin Scorsese";"Cannonball";"1975";"Action-Comédie-Drame" $
;-))
Zen my nuggets ;-)
Faites un geste pour l'environnement, fermez vos fenêtres et adoptez un manchot.
C'est presque ça :-)
-quand le champ que je veux supprimer (année du film) comporte un ##
ça donne un retour ligne prématuré... et le champs (année du film apparaît encore)...
-les deux premiers champs fixes "Nationalité" et "Realisateur"
ne reviennent pas systématiquement en chaque début de ligne
en tout cas merci beaucoup, je continue d'essayer de mon côté, sur bien meilleures bases :-)
-quand le champ que je veux supprimer (année du film) comporte un ##
ça donne un retour ligne prématuré... et le champs (année du film apparaît encore)...
-les deux premiers champs fixes "Nationalité" et "Realisateur"
ne reviennent pas systématiquement en chaque début de ligne
en tout cas merci beaucoup, je continue d'essayer de mon côté, sur bien meilleures bases :-)
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 407
3 janv. 2012 à 19:09
3 janv. 2012 à 19:09
Euh... par rapport à ton exemple je ne peux pas faire mieux ;-((
Ou il y a des trucs que je n'ai pas pigé ;-\
-quand le champ que je veux supprimer (année du film) comporte un ##
ça donne un retour ligne prématuré... et le champs (année du film apparaît encore)...
Pas chez moi ;-\
-les deux premiers champs fixes "Nationalité" et "Realisateur"
ne reviennent pas systématiquement en chaque début de ligne
Dans mon exemple si ;-\
Forcément si ton fichier original est différent de l'exemple donné, le risque de bugs n'est pas exclu ;-(
Ou il y a des trucs que je n'ai pas pigé ;-\
-quand le champ que je veux supprimer (année du film) comporte un ##
ça donne un retour ligne prématuré... et le champs (année du film apparaît encore)...
Pas chez moi ;-\
-les deux premiers champs fixes "Nationalité" et "Realisateur"
ne reviennent pas systématiquement en chaque début de ligne
Dans mon exemple si ;-\
Forcément si ton fichier original est différent de l'exemple donné, le risque de bugs n'est pas exclu ;-(
s/||/";"/g s/ ## /"\n"/g
ça je comprends bien, ça marche... remplacer les double pipe par ";" et ## par retour ligne.
Par contre
s/|#0-9#0-9*|//g
cette ligne c'est pour supprimer le champs année du film?
parfois il peut il avoir du texte pour les années de sortie genre "mille neuf cent quatre vingt"
C'est peut-être ça le problème?
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 407
3 janv. 2012 à 20:08
3 janv. 2012 à 20:08
cette ligne c'est pour supprimer le champs année du film?
Oui.
parfois il peut il avoir du texte pour les années de sortie genre "mille neuf cent quatre vingt"
C'est peut-être ça le problème?
Ben oui ;-((
Oui.
parfois il peut il avoir du texte pour les années de sortie genre "mille neuf cent quatre vingt"
C'est peut-être ça le problème?
Ben oui ;-((
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 407
3 janv. 2012 à 20:18
3 janv. 2012 à 20:18
Essaie avec "mise_en_forme.sed" comme ça :
s/||[^|]*||//1 s/\(## [^|]*|\)|[^|]*|/\1/g s/||/";"/g s/ ## /"\n"/g s/\([^;]*;[^;]*;\)\([^\n]*\n\)\(.*\)/\1\2\1\3/ P D
mamiemando
Messages postés
33079
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 avril 2024
7 749
3 janv. 2012 à 10:48
3 janv. 2012 à 10:48
Effectivement la commande sed (awk et vim permettent aussi d'y parvenir) permet de répondre au problème. A première vue :
- il faut substituer tous les || en ;
- il faut substituer tous les ## en -
De base pour remplacer un motif "aaa" en la chaîne "bbb" et sur toutes les occurrences de aaa sur une ligne dans un fichier appelé toto, la syntaxe est :
... ou encore (pratique quand aaa ou bbb comportent des /) :
Exemple :
Dans le cas général, aaa est en réalité une expression rationnelle (c'est pour cela que j'ai parlé de "motif"), il faut donc éventuellement regardé un cours à ce sujet :
https://fr.wikipedia.org/wiki/Expression_rationnelle
Tu peux également regarder le man de sed, tu verras que \1, \2 etc... permettent d'extraire des morceaux du motif (aaa dans mon premier exemple) en vue de de les réutiliser dans bbb. Tu as des exemples ici :
https://fr.wikipedia.org/wiki/Stream_Editor
Le truc c'est que tu sembles avoir plusieurs films par ligne, et du coup ce n'est pas super clair. Est-ce que tu as une ligne par réalisateur ou il peut y avoir d'autres cas de figure ? Ne perd pas de vue que tu peux lancer plusieurs commandes sed pour convertir ton fichier et que leur ordre est important.
Une fois le sed effectué tu pourras importer ton fichier grâce à la directive COPY FROM en SQL.
https://www.postgresql.org/docs/9.0/sql-copy.html
Bonne chance
- il faut substituer tous les || en ;
- il faut substituer tous les ## en -
De base pour remplacer un motif "aaa" en la chaîne "bbb" et sur toutes les occurrences de aaa sur une ligne dans un fichier appelé toto, la syntaxe est :
sed -i 's/aaa/bbb/g' toto
... ou encore (pratique quand aaa ou bbb comportent des /) :
sed -i 's%aaa%bbb%g' toto
Exemple :
(mando@aldur) (~) $ cat toto "Martin Scorsese";"Mad Max||1979||Action||Raging Bull||1980##1981||Drame||Cannonball||1975||Action##Comédie##Drame" (mando@aldur) (~) $ sed -i 's/||/;/g' toto (mando@aldur) (~) $ cat toto "Martin Scorsese";"Mad Max;1979;Action;Raging Bull;1980##1981;Drame;Cannonball;1975;Action##Comédie##Drame"
Dans le cas général, aaa est en réalité une expression rationnelle (c'est pour cela que j'ai parlé de "motif"), il faut donc éventuellement regardé un cours à ce sujet :
https://fr.wikipedia.org/wiki/Expression_rationnelle
Tu peux également regarder le man de sed, tu verras que \1, \2 etc... permettent d'extraire des morceaux du motif (aaa dans mon premier exemple) en vue de de les réutiliser dans bbb. Tu as des exemples ici :
https://fr.wikipedia.org/wiki/Stream_Editor
Le truc c'est que tu sembles avoir plusieurs films par ligne, et du coup ce n'est pas super clair. Est-ce que tu as une ligne par réalisateur ou il peut y avoir d'autres cas de figure ? Ne perd pas de vue que tu peux lancer plusieurs commandes sed pour convertir ton fichier et que leur ordre est important.
Une fois le sed effectué tu pourras importer ton fichier grâce à la directive COPY FROM en SQL.
https://www.postgresql.org/docs/9.0/sql-copy.html
Bonne chance
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
yann747
Messages postés
128
Date d'inscription
mardi 25 octobre 2011
Statut
Membre
Dernière intervention
13 octobre 2021
2
3 janv. 2012 à 15:30
3 janv. 2012 à 15:30
Merci pour vos réponses, je teste ça je vous en dis des nouvelles :-)
J'ai testé vos solutions, ça marche bien! Top
par contre la structure du CSV que j'ai à traité à été "un peu" modifiée:
Les deux premiers champs du fichier source reviennent toujours, le quatrième doit être supprimé, (qu'il contienne "##" ou non)... Du coup "##" a pour seule fonction un retour ligne.
Le champ supprimé devient ensuite le deuxième après "##"
Schématiquement:
1 2 3 (4) 5 6 7 8 9##10 (11) 12 13 14 15 16##17 (18) 19 20 21 22 23
()= supprimé
Devient
1 2 3 5 6 7 8 9
1 2 10 12 13 14 15 16
1 2 17 19 20 12 22 23
Ps: chaque ligne au final a toujours 8 items.
Tout ça est un peu compliqué, j'espère être assez clair (pas sûr...)
J'ai fait des test cet après-midi, avec sed, mais sans succès...
Voici donc un nouvel exemple, cette fois-ci définitif:
Exemple
"Americain";"Martin Scorsese";"Mad Max||1979||Action||Mel Gibson||Joanne Samuel||Steve Bisley||Tim Burns ## Raging Bull||1980##1981||Drame||Robert De Niro||Cathy Moriarty||Joe Pesci||Frank Vincent ## Cannonball||1975||Action||David Carradine||Bill McKinney||Veronica Hamel||Gerit Graham" \retour ligne
"Americain";"Martin Scorsese";"Mad Max";"Action";"Mel Gibson";"Joanne Samuel";"Steve Bisley";"Tim Burns" \retour ligne
"Americain";"Martin Scorsese";"Raging Bull";"Drame";"Robert De Niro";"Cathy Moriarty";"Joe Pesci";"Frank Vincent" \retour ligne
"Americain";"Martin Scorsese";"Cannonball";"Action-Comédie-Drame";"David Carradine";"Bill McKinney";"Veronica Hamel";"Gerit Graham" \retour ligne
séparateur dans le champs: || (en nombre fixe)
Retour ligne: ## (en nombre variable)
Je sais, ça donne pas trop envie de répondre... :-/
par contre la structure du CSV que j'ai à traité à été "un peu" modifiée:
Les deux premiers champs du fichier source reviennent toujours, le quatrième doit être supprimé, (qu'il contienne "##" ou non)... Du coup "##" a pour seule fonction un retour ligne.
Le champ supprimé devient ensuite le deuxième après "##"
Schématiquement:
1 2 3 (4) 5 6 7 8 9##10 (11) 12 13 14 15 16##17 (18) 19 20 21 22 23
()= supprimé
Devient
1 2 3 5 6 7 8 9
1 2 10 12 13 14 15 16
1 2 17 19 20 12 22 23
Ps: chaque ligne au final a toujours 8 items.
Tout ça est un peu compliqué, j'espère être assez clair (pas sûr...)
J'ai fait des test cet après-midi, avec sed, mais sans succès...
Voici donc un nouvel exemple, cette fois-ci définitif:
Exemple
"Americain";"Martin Scorsese";"Mad Max||1979||Action||Mel Gibson||Joanne Samuel||Steve Bisley||Tim Burns ## Raging Bull||1980##1981||Drame||Robert De Niro||Cathy Moriarty||Joe Pesci||Frank Vincent ## Cannonball||1975||Action||David Carradine||Bill McKinney||Veronica Hamel||Gerit Graham" \retour ligne
"Americain";"Martin Scorsese";"Mad Max";"Action";"Mel Gibson";"Joanne Samuel";"Steve Bisley";"Tim Burns" \retour ligne
"Americain";"Martin Scorsese";"Raging Bull";"Drame";"Robert De Niro";"Cathy Moriarty";"Joe Pesci";"Frank Vincent" \retour ligne
"Americain";"Martin Scorsese";"Cannonball";"Action-Comédie-Drame";"David Carradine";"Bill McKinney";"Veronica Hamel";"Gerit Graham" \retour ligne
séparateur dans le champs: || (en nombre fixe)
Retour ligne: ## (en nombre variable)
Je sais, ça donne pas trop envie de répondre... :-/
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 407
3 janv. 2012 à 18:46
3 janv. 2012 à 18:46
$ cat film.txt "Americain";"Martin Scorsese";"Mad Max||1979||Action||Mel Gibson||Joanne Samuel||Steve Bisley||Tim Burns ## Raging Bull||1980##1981||Drame||Robert De Niro||Cathy Moriarty||Joe Pesci||Frank Vincent ## Cannonball||1975||Action||David Carradine||Bill McKinney||Veronica Hamel||Gerit Graham" $ cat mise_en_forme.sed s/|[#0-9][#0-9]*|//g s/||/";"/g s/ ## /"\n"/g s/\([^;]*;[^;]*;\)\([^\n]*\n\)\(.*\)/\1\2\1\3/ P D $ sed -f mise_en_forme.sed film.txt "Americain";"Martin Scorsese";"Mad Max";"Action";"Mel Gibson";"Joanne Samuel";"Steve Bisley";"Tim Burns" "Americain";"Martin Scorsese";"Raging Bull";"Drame";"Robert De Niro";"Cathy Moriarty";"Joe Pesci";"Frank Vincent" "Americain";"Martin Scorsese";"Cannonball";"Action";"David Carradine";"Bill McKinney";"Veronica Hamel";"Gerit Graham" $