Kan jeg bruke bash-variabelerstatning for å trekke ut et stykke av en variabel basert på en delimeter? Jeg prøver å få det umiddelbare katalognavnet til et filnavn (i dette tilfellet foo). 
$ filename=./foo/bar/baz.xml 
Jeg vet at jeg kunne gjøre noe sånt som
echo $filename | cut -d "/" -f 2 
eller
echo $filename | awk -F "/" "{print $2}" 
 men det » s blir sakte å forkaste awk / cut for flere filnavn. 
Jeg gjorde en liten profilering av de forskjellige løsningene , ved hjelp av de virkelige filene mine:
ekko | klipp:
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 forslagene var en enorm forbedring i forhold til mine eksisterende ideer, men den variable erstatningen er raskest fordi den ikke krever forking av nye prosesser.
Kommentarer
- gnu.org/software/bash/manual / html_node / …
 - Send alle filnavnene til en påkalling av awk, og det vil være betydelig raskere enn noen løsning i ren bash
 - Kan du ikke bruke en matrise, kan du gjøre alt på en gang og deretter sette den i en ny matrise?
 
Svar
 Du kan fjerne den korteste ledende understrengen som samsvarer med */ 
tmp="${filename#*/}" 
 og deretter fjerne den lengste etterfølgende understreng som samsvarer med /* 
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 jokertegn det ser ut til å fungere med doble eller enkle anførselstegn –
 f="a?b?c" $(IFS="?"; set $f; echo $1) a echo $f a*b*c (IFS="*"; set $f; echo $1) a 
ja, du må deaktivere IFS tilbake til standard
 unset IFS 
Kommentarer
- Ooh, jeg liker det.
 -  Dette er vanligvis også min foretrukne metode, men husk at Bash støtter bare 
$1til$9ved hjelp av denne syntaksen. For tiende og senere argumenter må${10}-skjemaet brukes. -  Fungerer ikke ' t når 
$finneholder jokertegn. Og du må gjenoppretteIFSetterpå (eller gjør dette i en kommandosubstitusjon, for å få verdien av et felt, og som fjerner etterfølgende nye linjer). -  Eksemplet fungerer isolert (inne i Git bash på Windows), men når jeg piper fra finn-kommandoen får jeg denne feilen: 
echo: write error: Bad address. -  Ok, ser ut som Jeg må 
unset IFShver gang. 
Svar
 Feed listen til awk for å øke hastigheten: 
awk -F "/" "{print $2}" < <(find /usr) awk -F "/" "{print $2}" < inputfile 
Demonstrasjon:
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 ikke bruke kommandoen» dirname «i stedet for alt dette awk / sed / klippe ting?
filename=./foo/bar/baz.xml dirname $filename 
Utbytter:
./foo/bar 
Kommentarer
- I dette tilfellet lette jeg etter den umiddelbare katalogen, ikke hele katalogbanen.