A következő bash szintaxis ellenőrzi, hogy a param
nem “üres-e:
[[ ! -z $param ]]
Például:
param="" [[ ! -z $param ]] && echo "I am not zero"
Nincs kimenet és finom.
De amikor param
egy (vagy több) szóköz kivételével üres, akkor az eset különbözik:
param=" " # one space [[ ! -z $param ]] && echo "I am not zero"
“Nem vagyok nulla “kimenet.
Hogyan változtathatom meg a tesztet úgy, hogy a csak szóközöket tartalmazó változókat üresnek tekintsem? li> From man test
: -z STRING - the length of STRING is zero
. Ha a $param
összes helyet el akarja távolítani, használja a ${param// /}
trim()
funkció beépítve van egyáltalán * nix? Olyan sokféle hack, hogy valami olyasmit érjünk el … [[ ! -z $param ]]
egyenértékű a test ! -z $param
. Válasz
Először vegye figyelembe, hogy a -z
teszt kifejezetten erre vonatkozik:
a karakterlánc hossza nulla
Vagyis egy csak szóközt tartalmazó karaktersorozat nem legyen igaz a -z
alatt, mert nem nulla hosszúságú.
Azt akarod, hogy távolítsd el a szóközöket a változóból a mintacsere paraméter kibővítése :
[[ -z "${param// }" ]]
Ez kibővíti a param
változó, és a (egyetlen szóköz) minta összes egyezését lecseréli semmire, így egy olyan karaktersorozat kibővül egy üres karakterlánc.
A működésének aprósága az, hogy ${var/pattern/string}
a pattern
első leghosszabb meccsét string
váltja fel. Amikor a pattern
/
-vel kezdődik (mint fent), akkor az helyettesíti az összes mérkőzést. Mivel a csere üres, elhagyhatjuk a végső /
és a string
értéket:
$ {paraméter / minta / karakterlánc}
A minta kibővül, hogy ugyanúgy mintát állítson elő, mint a fájlnév kibontásában. A Paraméter kibővül, és a minta értéke és az értéke közötti leghosszabb egyezést a karakterlánc váltja fel. Ha a minta ’/’ betűvel kezdődik, akkor a minta minden egyezését string re cseréljük. Általában csak az első mérkőzést cserélik ki. … Ha a string értéke nulla, a minta egyezései törlődnek, és a / következő minta elhagyható.
Mindezek után az összes szóköz törléséhez végül a ${param// }
gombra kattintunk.
Vegye figyelembe, hogy bár jelen van ksh
(ahol keletkezett), zsh
és bash
, ez a szintaxis nem POSIX és nem használható a sh
szkriptekben.
Megjegyzések
Válasz
Az egyszerű módszer Annak ellenőrzése, hogy egy karakterlánc csak karaktereket tartalmaz-e egy engedélyezett készletben, az nem engedélyezett karakterek jelenlétének tesztelése.Így annak tesztelése helyett, hogy a karakterlánc csak szóközöket tartalmaz-e, tesztelje, hogy a karakterlánc tartalmaz-e a szóközön kívül más karaktert is. A bash, ksh vagy zsh fájlokban:
if [[ $param = *[!\ ]* ]]; then echo "\$param contains characters other than space" else echo "\$param consists of spaces only" fi
A „Csak szóközökből áll” egy üres (vagy nem beállított) változó esete.
Érdemes tesztelni bármely szóköz karaktert. A [[ $param = *[^[:space:]]* ]]
használatával használhatja a területi beállításokat, vagy bármely más, a szóköz karakterek kifejezett listáját, amelyeket tesztelni szeretne, pl. [[ $param = *[$" \t\n"]* ]]
a szóköz, a tabulátor vagy az újsor teszteléséhez.
Karakterlánc illesztése egy mintához =
[[ … ]]
egy ksh kiterjesztés (a bash és a zsh fájlokban is jelen van). Bármely Bourne / POSIX stílusban használhatja az case
konstrukciót, hogy a karakterláncot egy mintához illessze. Ne feledje, hogy a szokásos héjminták a !
paranccsal tagadják meg a karaktereket, nem pedig a ^
-t, mint a legtöbb reguláris kifejezés-szintaxisban. div id = “44aad5f0a0”>
A szóköz karakterek teszteléséhez az $"…"
szintaxis a ksh / bash / zsh-re jellemző; szó szerint beillesztheti ezeket a karaktereket a szkriptjébe (vegye figyelembe, hogy egy újsornak idézőjelek között kell lennie, mivel a backslash + newline semmivé bővül), vagy létrehozhatja őket, pl.
whitespace=$(printf "\n\t ") case "$param" in *[!$whitespace]*) echo "\$param contains non-whitespace characters";; *) echo "\$param consists of whitespace only";; esac
Megjegyzések
- Ez majdnem kiváló – de egyelőre nem válaszol a feltett kérdésre. Jelenleg meg tudja különböztetni az unset vagy üres shell változót és a csak szóközt tartalmazó változót. Ha elfogadja a javaslatomat, hozzáadja a param kibővítési űrlapot, amelyet még nem alakított át más olyan válasz, amely kifejezetten teszteli a shell változó beállítását – mármint
${var?not set}
– átmegy a teszten és túléli biztosítaná, hogy az*)
case
paraméterhez illeszkedő változó például végleges választ adjon. - Javítás – ez valójában válaszolna az eredetileg feltett kérdésre, de azóta úgy szerkesztették, hogy alapvetően megváltoztatja a kérdés jelentését, és ezért érvényteleníti válaszát.
-
[[ $param = *[!\ ]* ]]
szükséges amksh
mezőben.
Válasz
POSIXly:
case $var in (*[![:blank:]]*) echo "$var contains non blank";; (*) echo "$var contains only blanks or is empty or unset" esac
Megkülönböztetés üres , nem üres , empty , unset :
case ${var+x$var} in (x) echo empty;; ("") echo unset;; (x*[![:blank:]]*) echo non-blank;; (*) echo blank esac
[:blank:]
vízszintes térköz karakterekre vonatkozik (szóköz és tabulátor A-ban SCII, de valószínűleg van még néhány az Ön országában; egyes rendszerek tartalmazzák a nem törhető helyet (ahol elérhető), egyesek nem fogják “t” -et kapni. Ha függőleges távolságú karaktereket is szeretne (például újsor vagy űrlap-feed), cserélje le a [:blank:]
a következővel: [:space:]
.
Megjegyzések
- A POSIXly ideális, mert a (valószínűleg jobb) kötőjel.
- Úgy tűnik, hogy a
zsh
problémája van a[![:blank:]]
vel, ez felveti a:b
érvénytelen módosító. Ash
ésksh
emulációkban nem emelt eseményt találtak a következőhöz:[
- @cuonglm, mit próbáltál? A
var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'
számomra rendben van. A nem talált esemény csak interaktív héjakra szól. - @St é phaneChazelas: Ah, igaz, interaktív héjakkal próbálkoztam. Az
:b
érvénytelen módosító kissé furcsa. - @FranklinYu, OS / X rendszeren
sh
--enable-xpg-echo-default
és--enable-strict-posix-default
felépítéssel, hogy Unix-kompatibilis legyen (ami magában foglalja a lap kiírása).
Válasz
Az egyetlen megmaradó ok az írásra egy shell szkript a jó szkript nyelvű szkript helyett, ha a szélsőséges hordozhatóság mindenek felett álló probléma. Az örökölt /bin/sh
az egyetlen dolog, amiben biztos lehetsz, de például a Perl inkább valószínűleg több platformon elérhető, mint a Bash. Ezért soha ne írjon olyan shell parancsfájlokat, amelyek olyan funkciókat használnak, amelyek nem „igazán univerzálisak – és ne feledje, hogy több saját Unix-gyártó lefagyasztotta a shell környezetét a POSIX.1-2001 előtt .
Van egy hordozható módszer a teszt elvégzésére, de a tr
-et kell használnia:
[ "x`printf "%s" "$var" | tr -d "$IFS"`" = x ]
(A $IFS
alapértelmezett értéke kényelmesen szóköz, tabulátor és újsor.)
(A printf
a beépített maga is foltosan hordozható, de erre támaszkodva sokkal kevesebb gond, mint kitalálni, hogy melyik echo
változata van.)
Megjegyzések
- Ez ‘ egy kicsit összezavarodott.A szokásos hordozható módszer annak tesztelésére, hogy egy karakterlánc tartalmaz-e bizonyos karaktereket, a
case
. - @Gilles Nem hiszem, hogy ‘ lehetséges
case
gömböt írni olyan karakterláncot észlel, amely vagy üres, vagy csak szóköz karaktereket tartalmaz. (Egyszerű lenne egy regexp használatával, decase
nem ‘ nem csinál regexps-t. A válaszodban szereplő konstrukció nyert ‘ nem működik, ha törődnek az új sorokkal.) - Szóközöket adtam példaként a válaszomban, mert ez a ‘ kérdés kérte. ‘ ugyanolyan könnyű tesztelni a szóköz karaktereket:
case $param in *[![:space:]]*) …
. Ha tesztelni akarja aIFS
karaktereket, használhatja a*[$IFS]*
mintát. - @mikeserv komolyan védekező szkript, az IFS-t kifejezetten
<space><tab><newline>
-re állította az elején, majd soha többé nem érinti. Úgy gondoltam, hogy a ‘ figyelemelterelés lehet. - A minták változóit illetően úgy gondolom, hogy ez minden Bourne-verzióban és minden POSIX-héjban működik; extra kódra lenne szükség az esetminták észleléséhez és a változó bővítés kikapcsolásához, és ‘ nem tudok okot találni erre. Van néhány példányom a
.profile
-ben, amelyet sok Bourne-kagyló hajtott végre. Természetesen a[$IFS]
nem fog ‘ t csinálni, amit szándékolt, ha aIFS
bizonyos nem alapértelmezett értékek (üres (vagy nincs beállítva),]
-et tartalmaznak, kezdve!
vagy^
) .
Válasz
if [[ -n "${variable_name/[ ]*\n/}" ]] then #execute if the the variable is not empty and contains non space characters else #execute if the variable is empty or contains only spaces fi
Megjegyzések
- ezzel megszűnik minden szóköz karakter, nemcsak egyetlen szóköz, ugye? köszönöm
Válasz
A teszteléshez, ha a változó üres vagy szóközt tartalmaz, a következő kódot is használhatja:
${name:?variable is empty}
Hozzászólások
- Úgy gondolom, hogy a válaszát lecsökkentették, mert a ” vagy szóközöket tartalmazhat ” nem igaz.
- legyen óvatos – ez megöli az aktuális héjat. Jobb, ha egy (: $ {subshell?}) -Be tesszük. Továbbá – ami a stderr-be fog írni – valószínűleg átirányítást szeretne. És a legfontosabb , amely a ‘ változó tényleges értékét értékeli, ha az nincs beállítva vagy nulla. Ha ‘ parancs van bent, akkor csak futtatta. ‘ az a legjobb, ha ezt a tesztet a
:
eszközön futtatja. - hogyan fogja megölni a shellt. és u ezt is tesztelheti, először definiálja a
name=aaaa
parancsot, majd futtassa ezt a parancsotecho ${name:?variable is empty}
kinyomtatja a változó nevének értékét, és most futtatja ezt a parancsotecho ${name1:?variable is empty}
kinyomtatja a -sh: name1: változó üres - Igen –
echo ${name:?variable is empty}
vagy$name
‘ nem null értékű értéket vesz fel, vagy megöli a héjat. Tehát ugyanebből az okból nem kell ‘ t tennieprompt > $randomvar
, és${var?}
– ‘ sa parancs van ott, valószínűleg ‘ fog futni – és te nem ‘ t nem tudom mi ez. Egy interaktív héjnak nem kell ‘ leállnia – ezért a tiéd nem ‘ t. Ennek ellenére, ha meg akar nézni néhány tesztet, itt sok van . Ez nem ‘ t elég hosszú ideig …
Válasz
Az általad közzétett kód: [[ ! -z $param ]] && echo "I am not zero"
I am not zero
A param vagy nincs beállítva / nincs meghatározva, vagy üres (a bash, a ksh és a zsh formátumban).
To is nyomtassa ki, ha a param csak szóközöket tartalmaz (szóközök eltávolítása), POSIXly (a héjak szélesebb köréhez):
[ -z "${param#"${param%%[! ]*}"}" ] && echo "empty"
Magyarázat:
- A
${param# … }
eltávolít egy vezető szöveget. - Ezt a vezető szöveget a következő adja:
${param%%[! ]*}
- Ez -re bővül a bármely nem szóköz karakter, azaz az összes vezető szóköz.
A teljes kiterjesztés végeredménye, hogy az összes vezető szóköz eltávolításra kerül.
Ezt a kibővített eredményt 0 hosszúság esetén tesztelik.
- Ha az eredmény üres, akkor vagy a változó üres volt, vagy
- eltávolította a vezető tereket üressé tette.
Ezért, ha a teszt igaz, a változó vagy üres volt, vagy csak szóköz volt benne.
A koncepció könnyen bővíthető többre karaktertípusok. Fülek felvételéhez helyezzen explicit fület a zárójeles kifejezésbe:
[ -z "${param#"${param%%[! ]*}"}" ] && echo "empty"
vagy használjon változót az eltávolítandó karakterekkel:
var=$" \t" # in ksh, bash, zsh [ -z "${param#"${param%%[!$var]*}"}" ] && echo "empty"
vagy használhat néhány POSIX “karakterosztály kifejezést” (az üres szóközt és fület jelent):
[ -z "${param#"${param%%[![:blank:]]*}"}" ] && echo "empty"
Válasz
Annak ellenőrzése, hogy a változónak csak szóköze van-e, beleértve a többsoros változót is , próbálja ki ezt:
[[ $var = *[$" \t\n"]* ]]
Vagy xargs-szal:
[[ -z $(echo $var | xargs) ]]
Vagy sed-kel:
[[ -z $(sed "/^$/d" <<< $var) ]]
Válasz
Próbálja ki ezt:
$ [[ -z \`echo $n\` ]] && echo zero zero
sed
azt mondták … csakecho
az általuk mondott változó …${var/pattern/string}
, akkor nem ‘ t kell lennie[[ -z ${param/ /} ]]
a perjelek közötti szóközzel hogy legyen a minta, és semmi ne legyen a karakterlánc?[[ -z "${param// }" ]]
biztosan úgy néz ki, mint apattern
üres, és azreplacement string
egyetlen szóköz. AH! Most látomif pattern begins with a slash
hiányzott az a rész. tehát a minta/
, a karakterlánc pedig nem, ezért üres. Köszönöm.