Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

Bonjour,

j'ai un script shell qui contient la commande awk suivante



   


  awk 'BEGIN { FS=";"  } 
{ligne [NR] = $0 
 ref1 [NR]  = $2
 ref2 [NR]  = $3 
 ref3 [NR]  = $12
  }
END { 
      print NF
      print NR
    
     for ( i = 1 ; i <= NR ; i++ ){ printf( ligne )  }
    
     } ' fichier.txt



cette commande awk , récupere dans un premier temps toutes les lignes de fichier.txt en les mettant dans le tableau ligne ( et aussi différents champs séparés par ";" ) puis après imprime à l'écran toute les lignes du fichier .


ce que j'aimerais c'est qu'au lieu d'imprimer à l'écran toutes les lignes (dans la commande awk ) , ça envoie tout le tableau ligne (interne à la commande awk ) dans un tableau externe à la commande awk cad un tableau du script shell qui démarre la commande awk . pour être plus claire il me faudrait quelque chose du genre

#!/bin/sh

set Tableau 


   awk 'BEGIN { FS=";"  } 
{ligne [NR] = $0 
 ref1 [NR]  = $2
 ref2 [NR]  = $3 
 ref3 [NR]  = $12
  }
END { 
      print NF
      print NR
    
     for ( i = 1 ; i <= NR ; i++ ){ printf( Tableau=ligne )  }  
    
     } ' fichier.txt


reste du script qui utilise Tableau  




naturellement la ligne de code suivante (pour exporter en dehors de la commande awk le tableau ligne)
for ( i = 1 ; i <= NR ; i++ ){ printf( Tableau=ligne ) }

n'est pas bonne



d'où la question suivante ,comment faire pour exporter une valeur(et surtout tout un tableau ) en dehors de la commande awk et l'importer dans le script shell .



ps: ce problème rejoint mes précedentes questions à savoir obtenir la ligne d'un fichier très grand (plusieurs dizaines de milliers de lignes )
j'étais passé dans un premier temps par sed , puis par head | tail plus rapide que sed , mais plus la longueur du fichier est grande plus ça rame même avec head | tail . Donc l'astuce consiste en utilisant awk qui est très rapide (ou sed si quelqu'un sait faire ) à mettre toutes les lignes dans un tableau (donc en mémoire vive ) , comme ça le traitement est plus rapide après dans mons script shell

Poste le Monday 9 March 2009 12:49:56
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: riri

Dis nous alors ce que tu as comme entrée et ce que tu veux en sortie.

Poste le Monday 9 March 2009 14:13:45
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

Bonjour,


en entrée j'ai plusieurs fichiers type csv issus soit d'une base de donnée mdb ou d'un fichier excell . je dois réaliser des opérations sur les lignes de ces fichiers mais avec interaction entre les deux fichiers(pas de problème je sais faire ) ,mais avant je dois récuperer ces lignes soit une à une , soit dans un tableau . Jusqu'à maintenant je faisais comme ça :

set $( wc -l "$fichier1")
limite1=$1
echo "$limite1"

set $( wc -l "$fichier2")
limite2=$1
echo "$limite2"

i=1

while [ $i -le $limite1 ]
do
tableau1=$(head -n$i $fichier1 | tail -n1)
done


i=1

while [ $i -le $limite2 ]
do
tableau2=$(head -n$i $fichier2 | tail -n1)
done

....

puis commandes sur les deux tableaux et mettre dans un fichier .

....





Le problème est la récupération des lignes qui prend trop de temps .
donc il me faudrait :

-fonction qui met toutes les lignes des fichiers dans un tableau rapidement (moins de 10 secondes pour un fichier qui dépasse les 100 000 lignes ) . Je ne sais pas faire en shell rapidement ( ce que j'utilise met plusieurs minutes ...)

OU

-j'ai vu avec la commande awk.ça se fait en un clin d'oeil , seul problème le tableau crée reste interne à la commande awk et je ne sais pas comment le recuperer en dehors de la commande awk pour mon script shell .

Poste le Monday 9 March 2009 14:30:16
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

test :

\[ i \]

Poste le Monday 9 March 2009 14:32:30
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

retest [ i ]

Poste le Monday 9 March 2009 14:33:03
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

reretest

i=1

while [ $i -le $limite1 ]
do
tableau1 [ i ] =$(head -n$i $fichier1 | tail -n1)
done


i=1

while [ $i -le $limite2 ]
do
tableau2 [ i ] =$(head -n$i $fichier2 | tail -n1)
done

....

Poste le Monday 9 March 2009 14:34:02
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

Y a t il un moyen d'éditer ses messages

Merci

Poste le Monday 9 March 2009 14:36:45
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: NBaH

Bonjour,

Citation
distribution
Y a t il un moyen d'éditer ses messages
Non.

Mais qu'est-ce que tu veux faire avec (ba)sh, que ne pourrait pas faire awk ?

Poste le Monday 9 March 2009 15:25:09
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

gerer deux fichiers simultanement ?

awk '{commandes ... }' fichier1 fichier2

c'est possible ?

Poste le Monday 9 March 2009 15:44:03
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: NBaH

Citation
distribution
gerer deux fichiers simultanement ?

awk '{commandes ... }' fichier1 fichier2

c'est possible ?
Oui

Poste le Monday 9 March 2009 16:41:51
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

Tu es sûr ?

en supposant vrai , comment arrives tu à distinguer la variable NR associée à fichier1 de celle associée à fichier2 , et d'ailleurs comment distinguer les fichiers ?



sinon j'ai trouvé une astuce (un peu crade , mais de toute manière tout ce que je fais est moche ) : ajouter une ligne à fichier1 pour delimiter , puis de concatener fichier1 et fichier2 => fichier3 , puis à l'interieur de awk qui utilise fichier3 "séparer" les deux fichiers dans des tableaux grace à la ligne de délimitation ... si quelqu'un à une idée plus simple , je prends .

Poste le Monday 9 March 2009 17:07:06
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: riri

Oui c'est possible tu peux vérifier également sur quel fichier tu travail :
awk -F ';' '
 (FILENAME == "file1.txt") {
  [...]
 }

 (FILENAME == "file2.txt") {
  [...]
 }
 '
 file1.txt file2.txt

Poste le Monday 9 March 2009 17:17:23
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: NBaH


Poste le Monday 9 March 2009 17:25:15
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: riri

distribution a écrit:
-------------------------------------------------------
> Bonjour,
>
>
> en entrée j'ai plusieurs fichiers type csv issus
> soit d'une base de donnée mdb ou d'un fichier
> excell . je dois réaliser des opérations sur
> les lignes de ces fichiers mais avec interaction
> entre les deux fichiers(pas de problème je sais
> faire ) ,mais avant je dois récuperer ces lignes
> soit une à une , soit dans un tableau
Il me semble qu'un outil à été fait pour ça : mdbtools

A priori tu essais de faire des traitements sur des données issues d'une db tu devrait peut-être utiliser le SQL directement, non ?

Poste le Monday 9 March 2009 17:32:25
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

riri a écrit:
-------------------------------------------------------
> A priori tu essais de faire des traitements sur
> des données issues d'une db tu devrait peut-être
> utiliser le SQL directement, non ?

oui... l'idéal serait de créer un serveur LAMP + appli php (qui existe en partie maintenant ) et que tous les autres accédent ,gèrent leurs affaires en local via ces appli php dédiés etc ... Sauf que j'arrive dans une petite structure qui a quelques années et tout se fait avec des fichiers excel ou des mdb récuperer de logiciel fournis par les constructeurs ,chacun fait sa sauce ...un vrai bordel ... et surtout pas le temps de faire un travail en profondeur , faut tout faire dans l'urgence pour traiter le quotidien . peut être que d'ici 2 ou 3 mois j'aurais le temps de respirer pour pouvoir tout reprendre à zéro dans le calme ...et surtout virer définitivement les windows de la boite smiling smiley

Poste le Monday 9 March 2009 18:09:07
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

riri a écrit:
-------------------------------------------------------
> Oui c'est possible tu peux vérifier également
> sur quel fichier tu travail :
>
> awk -F ';' '
> (FILENAME == "file1.txt") {
> [...]
> }
>
> (FILENAME == "file2.txt") {
> [...]
> }
> '
> file1.txt file2.txt
>

j

Poste le Wednesday 13 May 2009 08:40:07
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: distribution

riri a écrit:
-------------------------------------------------------
> Oui c'est possible tu peux vérifier également
> sur quel fichier tu travail :
>
> awk -F ';' '
> (FILENAME == "file1.txt") {
> [...]
> }
>
> (FILENAME == "file2.txt") {
> [...]
> }
> '
> file1.txt file2.txt
>

j'avais pas répondu ...

j'apporte une précision (une astuce ) sur ce morceau de code donné par riri qui m'a été très utile .

awk -F ';' ' BEGIN { }
(FILENAME == "file1.txt") {
[...]
ligne1[NR]=$0
champ1x[NR]=$x
[...]
lg_file1=NR
}

(FILENAME == "file2.txt") {i=NR-lg_file1
[...]
ligne2=$0
champ2y=$y
[...]
lg_file2=i
}
END{ [...] }
'
file1.txt file2.txt

lg_file1 et lg_file2 permettent de réutiliser facilement dans END , les tableaux alimentés avant

Poste le Wednesday 13 May 2009 08:51:03
Répondre     Citer    
Re: interaction awk avec le script shell qui l'appelle
Envoyé par: rg421

distribution a écrit:
-------------------------------------------------------
> reretest
>
> i=1
>
> while [ $i -le $limite1 ]
> do
> tableau1 [ i ] =$(head -n$i $fichier1 | tail -n1)
> done
>
>
> i=1
>
> while [ $i -le $limite2 ]
> do
> tableau2 [ i ] =$(head -n$i $fichier2 | tail -n1)
> done
>
> ....

i=0
while read ligne; do
    tableau [ $i ] = "$ligne"
    ((i++))
done <fichier

est la méthode correcte, mais j'avoue que je n'en vois pas bien l'intérêt. ceci dit, ça passe en moins de 10 secondes:
rg ~/test $ time for ((i=0; i<100000; i++)); do echo "champ "{1,2,3,4}" ligne $i;" "dernier champ ligne $i" >> fichier; done

real	0m10.800s
user	0m9.866s
sys	0m0.928s
rg ~/test $ i=0
rg ~/test $ time while read ligne; do tableau[ $i]="$ligne"; ((i++)); done <fichier 

real	0m6.246s
user	0m6.052s
sys	0m0.190s
rg ~/test $ echo "${#tableau[ *]}"
100000

et il y a des trucs pour lesquels il n'y a pas photo

rg ~/test $ time sed -ne '85632 p' <fichier 
champ 1 ligne 85631; champ 2 ligne 85631; champ 3 ligne 85631; champ 4 ligne 85631; dernier champ ligne 85631

real	0m1.072s
user	0m1.059s
sys	0m0.010s
rg ~/test $ time awk 'NR==85632' fichier
champ 1 ligne 85631; champ 2 ligne 85631; champ 3 ligne 85631; champ 4 ligne 85631; dernier champ ligne 85631

real	0m0.103s
user	0m0.085s
sys	0m0.018s
rg ~/test $ time head -n85631 fichier | tail -n1
champ 1 ligne 85630; champ 2 ligne 85630; champ 3 ligne 85630; champ 4 ligne 85630; dernier champ ligne 85630

real	0m0.083s
user	0m0.054s
sys	0m0.029s

Poste le Tuesday 26 May 2009 21:39:36
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
interaction awk avec le script shell qui l'appelle
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