Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/09/2007, 16h25   #1
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
Par défaut Formatage de fichier csv

Bonjour

Je cherche à redonner à un fichier csv (issu d xls) une structure ou le nombre de colonnes est constant (4 dans l exemple ci-dessous)

Je vous expose mon problème par l'exemple

Le fichier en entré

Citation:
1;2;3;4
10;20;"ceci est
une seule colonne";40
100;200;300;400
Resultat "recherché" (avoir un nombre de colonne constant)

Citation:
1;2;3;4
10;20;"ceci est une seule colonne";40
100;200;300;400
OS : HP-UX
Shell : ksh

Merci de votre aide
tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 16h34   #2
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Faut-il se baser sur les guillemets ouverts (et chercher les guillemets fermés associés) ou juste sur le nombre de ";" dans la ligne ?

Peut-il y avoir un point-virgule dans la chaine ?
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 17h23   #3
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
Je pense qu il faut gerer les 2

Les guillemets me permette de localiser les lignes completes par rapport au lignes incompletes et les Guillemets les "Chaines" à reformater (la coller à la ligne precedente)

Normalement je ne dois par avoir de ; dans la partie Chaine

Car il peut y avoir le cas encore plus delicat (2 colonnes consecutives avec ce format de type texte d ou les guillements)
Citation:
10;20;"ceci est
une seule colonne";"et une
autre colonne";40
et on devrait avoir
Citation:
10;20;"ceci est une seule colonne";"et une autre colonne";40
PS: merci pour la rapidité de la réponse
tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 17h27   #4
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Une solution très simple (utilise gnu sed) :
Code :
sed -r ':a;/(.*;){3,}/b;N;s/\n/ /;ba'
Le 3 représente le nombre de points-virgules attendu dans chaque ligne (vu que c'est constant).

J'espère que ça suffira à tes besoins.

Edit : ok, il faudrait peut-être que je gère les guillemets, en fait.
Je reposte si j'y arrive.
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 17h43   #5
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
J aime bien ta notion du simple

Sinon dans sed pas gnu j ai pas l option -r

et sur une plate forme de production je ne suis pas pret de l avoir

Je ne pense par pouvoir echapper de toute façon à une boucle
tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 17h53   #6
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Essaie l'option -E de sed, alors. Ca fait la même chose (regexp étendues), ça dépend juste de la version du sed. Si tu n'as pas -E non plus, regarde le man ou dis-le, je modifierai le script.

Et pour la notion de simple, tu vas comprendre dans 2 lignes. Voilà une version qui regroupe les lignes quand il n'y a pas 3 points-virgules ou quand il y a un nombre impair de guillemets :

Code GNU sed :
sed -r ':a;/(.*;){3,}/{/^[^"]*(([^"]*"){2})*[^"]*$/b};N;s/\n/ /;ba'

La même chose, mais en beaucoup plus portable :
Code script.sed :
1
2
3
4
5
6
:a
/(.*;){3,}/{
  /^[^"]*(([^"]*"){2})*[^"]*$/b
}
N;s/\n/ /
ba
Si cette version ne gère pas tous les cas, il vaudra mieux passer à un outil plus évolué (perl, awk...).
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 18h02   #7
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
j ai un sed tres .... short
man
sed [-n] [-e script] [-f source_file] [file...]
tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 18h06   #8
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Dernière tentative :
Code :
1
2
3
4
5
6
:a
/\(.*;\)\{3,\}/{
  /^[^"]*\(\([^"]*"\)\{2\}\)*[^"]*$/b
}
N;s/\n/ /
ba
Sinon, j'abandonne. J'avais pourtant pris la peine de tester sur 3 sed différents.
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 18h18   #9
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
J avais essayé de mon coté avec tes scripts mais sans resultats

Et bien merci tout de meme pour les reponses

J en aurai vu un peu plus sur le sed

tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2007, 22h47   #10
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
Pas très compact, mais ça fonctionne avec tes exemples

liste.txt

Code :
1
2
3
4
5
6
7
8
 
1;2;3;4
10;20;"ceci est
une seule colonne";40
100;200;300;400 
10;20;"ceci est
une seule colonne";"et une 
autre colonne";40
Résultat du awk :

Code :
1
2
3
4
5
 
1;2;3;4
10;20;"ceci estune seule colonne";40
100;200;300;400 
10;20;"ceci estune seule colonne";"et une autre colonne";40


Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
awk -F";" '
{
	#-- CourantNbreQuote = Nombre de double-quote dans enreg. courant
	CourantNbreQuote=gsub(/"/,"\"",$0)
	CumulNbreQuote=CourantNbreQuote+PrecedNbreQuote
	if (CumulNbreQuote == 0) {
		PrecedNbreQuote=0
		print $0
		next
	}
	modulo=CumulNbreQuote%2
	if (modulo == 0) {
		PrecedNbreQuote=0
		print $0
		next
	}
	#
	#-- Nombre de double-quote impair, ecriture enreg. sans NewLine 
	#
	PrecedNbreQuote=CumulNbreQuote
	printf("%s",$0)
} ' liste.txt
__________________
Loi de Murphy:
La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2007, 10h08   #11
Invité de passage
 
Inscription : septembre 2004
Messages : 10
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 10
Points : 2
Points : 2
Merci
pil poil ce qu'il me faut

PS: je vais ressortir mon bouquin d'Awk


Y a t il moyen de gerer egalement ce cas ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
1;2;3;4
10;20;"ceci est
une
seule 
colonne";40
100;200;300;400
1000;2000;"ceci est
une seule 
colonne";"et 
une
autre 
colonne";4000
tyvix est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h48.


 
 
 
 
Partenaires

Hébergement Web