A bash változó szubsztitúciójának használata a cut / awk helyett

Használhatom bash változó szubsztitúcióját egy változó egy darabjának kivonására deliméter alapján? Megpróbálom megszerezni a fájlnév azonnali könyvtárnevét (ebben az esetben foo).

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

Tudom, hogy tehetek ilyet:

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

vagy

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

de ” s lassan elágazik awk / cut több fájlnévnél.

Kicsit profiloztam a különböző megoldásokat , valódi fájljaimat használva:

echo | vágás:

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

visszhang | awk:

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

@steeldriver változó helyettesítés / shell paraméter kibővítése:

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

@jai_s “IFS-küzdelem:

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

Mindkét javaslat óriási javulást hozott a meglévő elképzeléseimhez képest, de a változó helyettesítése a leggyorsabb, mert nem” t ” megköveteli az új folyamatok elágazását.

Megjegyzések

  • gnu.org/software/bash/manual / html_node / …
  • Küldje el az összes fájlnevet az awk egy invokációjába, és ez lényegesen gyorsabb lesz, mint a tiszta bash bármelyik megoldása
  • Nem használhat tömböt, mindet egyszerre megteheti, majd új tömbbe helyezi?

Válasz

Eltávolíthatja a (z) */

iv idnek megfelelő legrövidebb vezető részt, majd eltávolíthatja a leghosszabbat a /*

Válasz

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

vadkártyával, amely úgy tűnik működik kettős vagy egyetlen idézőjel –

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

igen, vissza kell állítania az IFS-t az alapértelmezettre

 unset IFS 

Hozzászólások

  • Ó, ez tetszik.
  • Ez általában a preferált módszerem is, de ne feledje, hogy Bash csak $1$9 -ig támogatja ezt a szintaxist. A 10. és későbbi argumentumokhoz az ${10} űrlapot kell használni.
  • Nem működik, ha $f helyettesítő karaktereket tartalmaz. És utána vissza kell állítania a IFS -et (vagy ezt egy parancshelyettesítéssel kell megtennie, hogy megkapja a mező értékét, és ez levonja az új sorokat).
  • A példa elkülönítve működik (a Git bash belsejében Windows rendszeren), de amikor a keresési parancsról pipálok, a következő hibát kapom: echo: write error: Bad address.
  • Rendben, úgy néz ki, mint Minden alkalommal unset IFS kell.

Válasz

Feed a listát a awk fájlba a felgyorsítás érdekében:

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

Bemutató:

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 

Válasz

Miért nem használja a” dirname “parancsot az awk / sed / helyett / cuccot vágni?

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

Hozam:

./foo/bar 

megjegyzések

  • Ebben az esetben a közvetlen könyvtárat kerestem, nem pedig a teljes könyvtár elérési utat.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük