Brug af bash-variabelerstatning i stedet for cut / awk

Kan jeg bruge bash-variabelerstatning til at udtrække et stykke af en variabel baseret på en delimeter? Jeg prøver at få det umiddelbare biblioteksnavn på et filnavn (i dette tilfælde foo).

$ filename=./foo/bar/baz.xml 

Jeg ved, at jeg kunne gøre noget som

echo $filename | cut -d "/" -f 2 

eller

echo $filename | awk -F "/" "{print $2}" 

men det ” s bliver langsom til at forkaste awk / cut til flere filnavne.

Jeg lavede en lille profilering af de forskellige løsninger , ved hjælp af mine rigtige filer:

ekko | klip:

real 2m56.805s user 0m37.009s sys 1m26.067s 

ekko | awk:

real 2m56.282s user 0m38.157s sys 1m31.016s 

@steeldrivers variable substitution / shell parameter expansion:

real 0m0.660s user 0m0.421s sys 0m0.235s 

@jai_s “IFS-wrangling:

real 1m26.243s user 0m13.751s sys 0m28.969s 

Begge forslag var en enorm forbedring i forhold til mine eksisterende ideer, men den variable erstatning er hurtigst, fordi den ikke kræver forking af nye processer.

Kommentarer

  • gnu.org/software/bash/manual / html_node / …
  • Send alle filnavne til en påkaldelse af awk, og det vil være betydeligt hurtigere end nogen løsning i ren bash
  • Kan du ikke bruge en matrix, skal du gøre dem alle på én gang og derefter placere den i en ny matrix?

Svar

Du kan fjerne det korteste ledende understreng, der matcher */

tmp="${filename#*/}" 

og derefter fjerne den længste efterfølgende understreng, der matcher /*

Svar

 echo $f a/b/c $ (IFS="/";set $f; echo $1) a $ (IFS="/";set $f; echo $2) b $ (IFS="/";set $f; echo $3) c 

med wildcard det ser ud til at arbejde med dobbelt eller enkelt citater –

 f="a?b?c" $(IFS="?"; set $f; echo $1) a echo $f a*b*c (IFS="*"; set $f; echo $1) a 

ja, du bliver nødt til at frakoble IFS tilbage til standard

 unset IFS 

Kommentarer

  • Ooh, det kan jeg godt lide.
  • Dette er normalt også min foretrukne metode, men husk at Bash understøtter kun $1 til $9 ved hjælp af denne syntaks. Til 10. og senere argumenter skal ${10} -formularen bruges.
  • Fungerer ikke ' t, når $f indeholder jokertegn. Og du skal gendanne IFS bagefter (eller gør dette i en kommandosubstitution for at få værdien af et felt, og det fjerner efterfølgende nye linjer).
  • Eksemplet fungerer isoleret (inde i Git bash på Windows), men når jeg rører fra find-kommandoen, får jeg denne fejl: echo: write error: Bad address.
  • Okay, ligner Jeg skal unset IFS hver gang.

Svar

Feed listen til awk for at fremskynde den:

awk -F "/" "{print $2}" < <(find /usr) awk -F "/" "{print $2}" < inputfile 

Demonstration:

time awk -F "/" "{print $2; SUM++} END {print "number of directories found: " SUM}" < <(find /usr -type d) usr usr . . number of directories found: 16748 real 0m8.910s user 0m0.050s sys 0m0.050s 

Svar

Hvorfor bruger du ikke kommandoen” dirname “i stedet for alt dette awk / sed / klippe ting?

filename=./foo/bar/baz.xml dirname $filename 

Udbytter:

./foo/bar 

Kommentarer

  • I dette tilfælde ledte jeg efter den øjeblikkelige bibliotek, ikke den fulde katalogsti.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *