Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

Bonjour,

j'ai un fichier monfixhier.txt qui a environ 16000 lignes

j'ai le script suivant qui permet de récuperer les lignes de monfichier.txt pour récuperer une partie de chaque ligne et la mettre dans le fichier ref.txt


1   #!/bin/bash
2   chemin="/home/user/monfichier.txt"
3   chemin1="/home/user/ref.txt"
4
5
6
7   set $( wc -l $chemin)
8   ligne=$1
9   echo $ligne
10
11  for i in $(seq 2 $ligne )
12  do  
13     var=$(sed -n "$i"p $chemin)
14     nom=${var%%,*}
15     premier=${nom:0:1}
16     if [ $premier != '"' ]
17     then
18         echo $nom >> $chemin1
19     else 
20         reference=${nom#'"'}
21         reference2=${reference%'"'}
22         echo $reference2 >> $chemin1    
23     fi
24  done
25  exit 0


ce script fonctionne parfaitement ( en gros il prend de chaque ligne la partie avant la première virgule ,puis l'ajoute en tant que ligne dans le fichier ref.txt )

Le problème est le suivant . Je le trouve très très lent ,et je ne n'arrive pas à déterminer la portion qui ralentit l'exécution du script . Je penche pour la ligne 13 var=$(sed -n "$i"p $chemin) , mais je ne suis pas sûr car j'ai utilisé à peu près les même lignes mais d'une manière différente sur une script qui lui s'occupait d'un fichier contenant plus de 170 000 lignes ! et c'était assez rapide .

petite précision ce fichier monfichier.txt est issu d'un fichier.xls transformé en .csv via openoffice ( ce qui n'était pas le cas dans l'autre script rapide traitant plus de 170 000 lignes )


une autre question j'aimerais remplacer le script précédent par le code suivant



1   #!/bin/bash
2   chemin="/home/user/monfichier.txt"
3   chemin1="/home/user/ref.txt"
4
5  somme=0
6
7   set $( wc -l $chemin)
8   ligne=$1
9   echo $ligne
10
11  for i in $(seq 2 $ligne )
12  do  
       somme=$((somme+1))
13     var=$(sed -n "$i"p $chemin)
14     nom=${var%%,*}
15     premier=${nom:0:1}
16     if [ $premier != '"' ]
17     then
18         sed "$sommea\$nom"  $chemin1
19     else 
20         reference=${nom#'"'}
21         reference2=${reference%'"'}
22         sed  "$sommea\$reference2"  $chemin1    
23     fi
24  done
25  exit 0


cad j'ajoute la variable somme (ligne 5) et à chaque itération j'ajoute une ligne dans le fichier ref.txt avec la commande sed (ligne 18 et 22) . malheureusement ça ne fonctionne pas . Je n'ai pas trouvé sur le net de documentation claire(1) avec exemple permettant de résoudre mon cas à savoir ajouter une ligne au numéro de ligne indiquée par la variable $somme dans un fichier vide à l'origine :


(1)
[www.commentcamarche.net]
[jp.barralis.com]

Merci

Poste le Tuesday 17 February 2009 19:36:47
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

j'ajoute version de sed "GNU sed version 4.1.5"

Poste le Tuesday 17 February 2009 19:38:45
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: NBaH

Tu devrais approfondir tes connaissances sur sed, car une "simple" ligne sed résoudrait ton problème, mieux et plus rapidement.

Regarde cette page, certains liens sont morts, mais les survivants t'apporteront la solution que tu cherches, que ce soit pour extraire le début d'une ligne jusqu'à la première virgule, et rediriger la sortie vers un fichier, ou effectuer la même opération en numérotant les lignes; avec une ou deux commandes sed pipées.

Normalement, sur ton système, tu dois également disposer de cette page

source="/chemin/vers/fichier.in"
dest="/chemin/vers/fichier.out"
sed -n 's/\([^,]*\),.*/\1/w'"$dest"'' "$source"
--
source="/chemin/vers/fichier.in"
dest2="/chemin/vers/fichier2.out"
sed  = "$source" | sed -n 'N;s/\n/ /; s/\([^,]*\),.*/\1/w'"$dest2"''
Ça fonctionne ?

Poste le Tuesday 17 February 2009 20:39:16
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

Bonjour,

le bon sed est


source="/chemin/vers/fichier.in"
dest="/chemin/vers/fichier.out"
sed -e 's/^\([^,]*\),.*/\1/' "$source" > "$dest"


pour la rapidité il n'y a pas photo .

mois d'une seconde avec ta fonction sed d'une seule ligne ... 25 min et 46 seconde avec mon script de 20 lignes , il y a pas photo je vais utiliser dorénavant la fonction sed smiling smiley

Juste une petite question supplémentaire :

parmi les chaînes de caractère avant la première virgule , certaines peuvent être encadrées par des guillements d'autre non cad "motif" ou motif , et je ne dois récupérer que motif , c'est à dire que j'ai besoin de l'équivalent d'un if then else fi dans le sed . Il y a quelque chose de ce style ?


Merci

Poste le Wednesday 18 February 2009 10:03:12
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

bon je n'ai pas trouvé la condition pour virer les guillements , j'ai trouvé une solution (bancale ?) qui est : appliquer deux sed à la suite

sed -e 's/^[".]\([^,]*\)[".],.*/\1/' "$chemin" > "$chemin1"
sed -e 's/^\([^,]*\),.*/\1/' "$chemin1" > "$chemin2"

car le premier sed ne remplit pas completement l'objectif car même si il vire les guillemets du motif avant la première virgule , ajoute parfois tout le reste après la première virgule .

Poste le Wednesday 18 February 2009 10:46:13
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: NBaH

Oui, ça existe. Sur la première page que je t'ai donné, il y a cette référence.

Ça ferait
sed -n '/^"/!s/\([^,]*\),.*/\1/p'
si la ligne ne commence pas par un double-quote, la substitution est appliquée, et le résultat est affiché
...
?

Poste le Wednesday 18 February 2009 10:58:48
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

ça ne fonctionne pas , car il vire toute la ligne .

ce qu'il me faut c'est :

motif,.* donne motif
"motif",.* donne motif

question : y a t il quelque chose pour dire dans l'expression réguliere que un caractère peut être vide , être un guillement ET différent de la virgule

c'est à dire quelque chose du genre [[."]&&[^,]]

Poste le Wednesday 18 February 2009 11:31:38
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: NBaH

echo -e "le marsu, pilami\\n\"gaston et jeanne\", prunelle" |\
 sed -n '/^"/!s/\([^,]*\),.*/\1/p;/^"/s/"\([^,]*\)",.*/\1/p'
le marsu
gaston et jeanne
meuh, si ça marche ! ^^

Poste le Wednesday 18 February 2009 11:46:04
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: distribution

la ligne

sed -n '/^"/!s/\([^,]*\),.*/\1/p;/^"/s/"\([^,]*\)",.*/\1/p'

fonctionne très bien mais elle est trop compliquée pour moi , j'arrive pas à comprendre comment elle marche du moins l'étape après \1 . je préfére garder

1)sed -e 's/^[".]\([^,]*\)[".],.*/\1/' "$chemin" > "$chemin1"
2)sed -e 's/^\([^,]*\),.*/\1/' "$chemin1" > "$chemin2"


ceci dit même dans la ligne 1) et 2) plus simple , je ne comprends pas pourquoi je suis obligé de passer par deux lignes

la ligne 1) donne le résultat suivant :

"motif",.* => motif
motif,.* => motif,.*


c'est à dire elle fait correctement le travail pour les lignes dont le motif est encadré par "" mais ne touche pas aux lignes dont le motif n'est pas encadré par "" , d'où la nécessité de la deuxième ligne sed 2) pour finir le travail :

motif => motif
motif,.* => motif

Poste le Wednesday 18 February 2009 13:11:42
Répondre     Citer    
Re: methode pour traiter les lignes d'un fichier.txt
Envoyé par: NBaH

/^"/ - signifie _si_ la ligne commence par ", donc le contraire (si la ligne ne commence pas par " ) est /^"/!, et pour chaque condition, on applique une modification différente selon qu'il faut prendre en compte les ", ou pas.
Donc,
/^"/ ! s/\([^,]*\),.*/\1/ p ; /^"/ s/"\([^,]*\)",.*/\1/ p

Ceci fonctionne aussi:
sed -n 's/"\([^,]*\)",.*/\1/ p; s/\([^,]*\),.*/\1/ p'
Ça ne marche pas dans tous les cas, mais en général, ce que font deux sed, un seul peut le faire.

Par contre, je ne parviens pas non plus à utiliser des ou | performants pour les deux "

Poste le Wednesday 18 February 2009 14:34:33
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
methode pour traiter les lignes d'un fichier.txt
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons