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 aIFS
-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.