Käyttämällä bash-muuttujan korvaamista cut / awk: n sijasta

Voinko käyttää bash-muuttujan korvaamista poimimaan osan muuttujasta erottimen perusteella? Yritän saada tiedostonimen välitön hakemistonimi (tässä tapauksessa foo).

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

Tiedän, että voisin tehdä jotain

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

tai

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

mutta se ” s etenee hitaasti awk / cut useille tiedostonimille.

Profiloin vähän eri ratkaisuja , käyttäen oikeita tiedostoni:

kaiku | leikkaus:

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

kaiku | awk:

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

@steeldriver ”muuttujan korvaaminen / shell-parametrin laajennus:

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

@jai_s ”IFS-kamppailu:

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

Molemmat ehdotukset olivat valtava parannus nykyisiin ideoihini verrattuna, mutta muuttujan korvaaminen on nopeinta, koska se ei” t ” vaativat uusien prosessien haaroittamista.

Kommentit

  • gnu.org/software/bash/manual / html_node / …
  • Lähetä kaikki tiedostonimet yhteen awk-kutsuun ja se on huomattavasti nopeampi kuin mikään muu puhtaan bashin ratkaisu
  • Etkö voi käyttää matriisia, tee kaikki kerralla ja laita se sitten uuteen matriisiin?

Vastaa

Voit poistaa lyhimmän alimerkkijonon, joka vastaa */

tmp="${filename#*/}" 

ja poistaa sitten pisimmän

vastaus

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

villikortilla, jonka kanssa se näyttää toimivan kaksois- tai yksittäiset lainausmerkit –

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

kyllä, sinun on kumottava IFS takaisin oletusarvoon

 unset IFS 

Kommentit

  • Ooh, pidän siitä.
  • Tämä on yleensä myös suosituin menetelmäni, mutta pidä mielessä, että Bash tukee vain $1$9 kautta tällä syntaksilla. Kymmenennen ja sitä myöhempien argumenttien osalta on käytettävä ${10} -muotoa.
  • Ei toimi ' ei toimi, kun $f sisältää jokerimerkkejä. Ja sinun on palautettava IFS jälkikäteen (tai tee tämä komentokorvauksessa, jotta saat kentän arvon ja joka poistaa viimeiset uudet rivit).
  • Esimerkki toimii erikseen (Git bashin sisällä Windowsissa), mutta kun syötän hakukomentoa, saan tämän virheen: echo: write error: Bad address.
  • Okei, näyttää Minun on unset IFS joka kerta.

Vastaa

Syöte luetteloon awk sen nopeuttamiseksi:

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

Esittely:

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 

Vastaa

Miksi et käytä” dirname ”-komentoa tämän kaiken awk / sed / sijaan leikataan tavaraa?

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

Tuotto:

./foo/bar 

kommentit

  • Tässä tapauksessa etsin välitöntä hakemistoa, ei koko hakemistopolkua.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *