Hogyan tesztelhetem, hogy egy változó üres vagy csak szóközt tartalmaz?

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// /}

  • WOW nincs egyszerű trim() funkció beépítve van egyáltalán * nix? Olyan sokféle hack, hogy valami olyasmit érjünk el …
  • @ADTC $ (sed ‘ s / ^ \ s + | \ s + $ // g ‘ < < < $ string) számomra elég egyszerűnek tűnik. Miért érdemes újból feltalálni a kereket?
  • Mert fényesebb lehet
  • Csak annak megjegyzése, hogy [[ ! -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

    • use sed azt mondták … csak echo az általuk mondott változó …
    • Hmm. Ha ez ${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?
    • @JesseChisholm ” Mivel a helyettesítés üres, elhagyhatjuk a végső / és a karakterlánc értékét “; ” Ha az karakterlánc értéke nulla, a minta egyezései törlődnek, és a / következő minta kihagyva. ”
    • @MichaelHomer A válasz [[ -z "${param// }" ]] biztosan úgy néz ki, mint a pattern üres, és az replacement string egyetlen szóköz. AH! Most látom if 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.
    • bash megjegyzés: ha a set -o főnévhalmazban (set -u) fut, és a param nincs beállítva (semmint null vagy szóköz), akkor ez nem kötött változó hibát generál. (set + u; …..) mentesítené ezt a tesztet.

    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 a mksh 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ó. A sh és ksh 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 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, de case 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 a IFS 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 a IFS 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 parancsot echo ${name:?variable is empty} kinyomtatja a változó nevének értékét, és most futtatja ezt a parancsot echo ${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 tennie prompt > $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 

    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