← Back to team overview

sslug-teknik team mailing list archive

Re: Storke langsomt bash script

 

Martin Dupont Ahrentsen skrev:
> Hej i kloge folk bag keyboardet,
> 
> Jeg har et script som skal parse en en fil hvor den skal tjekke om nogle
> numre på nogle felter ligger indenfor nogle globale serier.
> 
> Filen t_pcl_ser indeholder ca 181.000 linier hvilket gør at det tager
> sindsygt lang tid at parse den.
> 
> formatet er som følgende:
> 
> 2080099992|92091661701|92091661800|N|N|Y|Y|N|DK||Y|
> 2080099997|09999700000|09999799999|N|N|Y|N|N|DK|6000|Y|
> 2080099997|92091293701|92091293800|N|N|Y|N|N|DK|6000|Y|
 ...

er der varierende antal felter?


> 
> ----------------start cut af script----------------

 ...snip...

> for i in `cat t_pcl_ser`
> do
>        testcustomerid=`echo $i | cut -d\| -f1`
>        teststartno=`echo $i | cut -d\| -f2`
>        testendno=`echo $i | cut -d\| -f3`
>        testactiveflag=`echo $i | cut -d\| -f4`
>        testprocflag001=`echo $i | cut -d\| -f5`
>        testprocflag002=`echo $i | cut -d\| -f6`
>        testprocflag003=`echo $i | cut -d\| -f7`
>        testprocflag004=`echo $i | cut -d\| -f8`
>        testcountrya2=`echo $i | cut -d\| -f9`
>        testzip=`echo $i | cut -d\| -f10`
>        testprocflag005=`echo $i | cut -d\| -f11`
> 
>        if [ \( ${teststartno} -ge ${startno1} -a ${testendno} -le
> ${endno1} \) -o \( ${teststartno} -ge ${startno2} -a ${testendno} -le
> ${endno2} \) -o \( ${teststartno} -ge ${startno3} -a ${testendno} -le
> ${endno3} \) ]
>        then
>                echo
> "${testcustomerid}|${teststartno}|${testendno}|${testactiveflag}|${testprocflag001}|Y|Y|${testprocflag004}|${testcountrya2}|${testzip}|${testprocflag005}|" 
>>> ${masterdatadir}/tmp/t_pcl_ser
>        else
>                echo  ${i} >> ${masterdatadir}/tmp/t_pcl_ser
>        fi
> done
> 
> ----------------end cut af script----------------
> 
> Er der en anden måde at skrive det på så hastigheden bliver sat i vejret
> eller skal det skrives i et andet sprog?

AWK er god til tekst-ind -> tekst-ud , regular expressions mv,
og AWK er relativ enkelt/simpelt.
Manualen med "man awk" dækker det meste.

Perl mfl. kunne også være en mulighed.

I ovenstående er  der bla. en del ekstra systenkald med "cut" (og måske echo),
måske det sløver .

bruger du Bash , så er der nogle ekstra muligheder indbygget :

1)
Bash har indbygget parameter expansion (se i manual til bash).
f.eks.
 ${i%%|*}  vil gøre det samme som echo $i | cut -d\| -f1`
at pille enkelte felter ud kan blive lidt bøvlet, men tager
man en ad gangen med ${i%|....} og ${i#....} er det muligt.

2)
hvis du ved at alle felter er adskilt af  |  , så kunne
du prøve med IFS:

OIFS=$IFS  # gem IFS
IFS=\|     # sæt til |
iflds=($i) # iflds er nu et array
IFS=$OIFS  # eventuelt retabler IFS

nu er alle parameter tilgængelig som array:
  ${iflds[0]}  , ${iflds[1]} , ...

og antal elementer er ${#iflds[*]}




References