Kuinka voin testata, onko muuttuja tyhjä vai sisältääkö vain välilyöntejä?

Seuraava bash-syntaksin avulla varmistetaan, että param ei ole ”tyhjä”:

 [[ ! -z $param ]] 

Esimerkiksi:

param="" [[ ! -z $param ]] && echo "I am not zero" 

Ei tulostetta ja sen hieno.

Mutta kun param on tyhjä yhtä (tai useampaa) välilyöntiä lukuun ottamatta, tapaus on erilainen:

param=" " # one space [[ ! -z $param ]] && echo "I am not zero" 

”En ole nolla ”on tulos.

Kuinka voin muuttaa testin siten, että muuttujat, jotka sisältävät vain välilyöntejä, pidetään tyhjinä?

Kommentit

  • Alkaen man test: -z STRING - the length of STRING is zero. Jos haluat poistaa kaikki välilyönnit kohdasta $param, käytä ${param// /}
  • WOW ei ole yksinkertaista trim() -funktiota Onko sinulla mitään nixiä? Niin monta erilaista hakkerointia saavuttaaksesi jotain niin yksinkertaista …
  • @ADTC $ (sed ’ s / ^ \ s + | \ s + $ // g ’ < < < $ merkkijono) näyttää minulle riittävän yksinkertaiselta. Miksi pyörä tulisi keksiä uudelleen?
  • Koska se voi olla kiiltävämpi
  • Pelkästään huomata, että [[ ! -z $param ]] vastaa test ! -z $param.

Vastaa

Huomaa ensin, että -z -testi on nimenomaisesti seuraava:

merkkijonon pituus on nolla

Eli vain välilyöntejä sisältävän merkkijonon ei ole tosi kohdassa -z, koska sen pituus on nollasta poikkeava.

Haluat poistaa poikkeamat muuttujasta mallin korvaavan parametrin laajennus :

[[ -z "${param// }" ]] 

Tämä laajentaa param muuttuja ja korvaa kaikki mallin (yksi välilyönti) osumat ilman mitään, joten merkkijono, jossa on vain välilyöntejä, laajennetaan tyhjä merkkijono.


miten tämä toimii on, että ${var/pattern/string} korvaa pattern: n ensimmäisen pisimmän ottelun string. Kun pattern alkaa / (kuten yllä), se korvaa kaikki ottelut. Koska korvaava osa on tyhjä, voimme jättää lopullisen / ja string arvon:

$ {parameter / pattern / string}

kuvio laajennetaan tuottamaan kuvio samalla tavalla kuin tiedostonimen laajennuksessa. Parametri laajennetaan ja kuvio : n pisin vastaavuus sen arvoon korvataan merkkijonolla . Jos kuvio alkaa /, kaikki kuvio -kohteet korvataan merkkijonolla . Normaalisti vain ensimmäinen ottelu korvataan. … Jos merkkijono on tyhjä, kuvio -kohteet poistetaan ja / seuraava kuvio voidaan jättää pois.

Kaiken tämän jälkeen lopetamme kaikkien välilyöntien ${param// } -toiminnon.

Huomaa, että vaikka ksh (mistä se on alkanut), zsh ja bash, tämä syntaksia ei ole POSIX, eikä sitä tule käyttää sh -skripteissä.

Kommentit

  • use sed he sanoivat … vain echo heidän sanomansa muuttujan …
  • Hmm. Jos se on ${var/pattern/string}, sen ei pitäisi ’ t olla [[ -z ${param/ /} ]] ja kauttaviivojen välinen tila olla malli eikä mitään sen jälkeen merkkijonoa?
  • @JesseChisholm ” Koska korvaus on tyhjä, voimme jättää lopullisen / ja merkkijonon arvon ”; ” Jos merkkijono on tyhjä, kuvion vastaavuudet poistetaan ja / seuraava kuvio voidaan poistaa jätetty pois. ”
  • @MichaelHomer Vastaus [[ -z "${param// }" ]] näyttää varmasti siltä, että pattern on tyhjä ja replacement string on yksi välilyönti. AH! Näen sen nyt if pattern begins with a slash Kaipasin sitä osaa. joten kuvio on / ja merkkijono jätetään pois ja on siten tyhjä. Kiitos.
  • perushuomautus: jos suoritetaan set -o-nimisarjassa (set -u) ja param-asetusta ei ole asetettu (nollan tai välilyönnin sijaan), niin tämä aiheuttaa sitomattoman muuttujavirheen. (set + u; …..) vapauttaa tämän testin.

Vastaa

Helppo tapa Jos haluat tarkistaa, että merkkijono sisältää merkkejä vain valtuutetussa sarjassa, on testattava luvattomien merkkien läsnäolo.Sen sijaan, että testaisit, sisältääkö merkkijono vain välilyöntejä, testaa, sisältääkö merkkijono muuta merkkiä kuin välilyönnin. Bashissa ksh tai zsh:

if [[ $param = *[!\ ]* ]]; then echo "\$param contains characters other than space" else echo "\$param consists of spaces only" fi 

”Koostuu vain välilyönneistä” sisältää tyhjän (tai asettamattoman) muuttujan.

Voit halutessasi testata minkä tahansa välilyönnin. Käytä [[ $param = *[^[:space:]]* ]] käyttääksesi kieliasetuksia tai mitä tahansa nimenomaista tyhjätilamerkkien luetteloa, jota haluat testata, esim. [[ $param = *[$" \t\n"]* ]] testataksesi välilyöntiä, sarkainta tai uutta riviä.

Merkkijonon sovittaminen malliin = [[ … ]] on ksh-laajennus (esiintyy myös bashissa ja zsh: ssä). Missä tahansa Bourne / POSIX-tyylissä voit käyttää case -rakennetta sovittamaan merkkijono malliin. Huomaa, että vakiomalliset kuorimallit käyttävät ! -merkkiä merkkijoukon hylkäämiseen ^ -toiminnon tavoin, kuten useimmissa säännöllisten lausekkeiden syntakseissa.

case "$param" in *[!\ ]*) echo "\$param contains characters other than space";; *) echo "\$param consists of spaces only";; esac 

Välilyöntien merkkien testaamiseksi syntaksi $"…" on ominaista ksh / bash / zsh: lle; voit lisätä nämä merkit komentosarjaasi kirjaimellisesti (huomaa, että uuden rivin on oltava lainausmerkeissä, koska taaksepäin viiva + uusi viiva laajenee tyhjäksi), tai luoda ne, esim.

whitespace=$(printf "\n\t ") case "$param" in *[!$whitespace]*) echo "\$param contains non-whitespace characters";; *) echo "\$param consists of whitespace only";; esac 

Kommentit

  • Tämä on melkein erinomainen – mutta toistaiseksi se ei vastaa kysymykseen esitetyllä tavalla. Tällä hetkellä se voi kertoa eron tyhjentämättömän – tai -muuttujan ja vain välilyöntejä sisältävän välillä. Jos hyväksyt ehdotukseni, lisää param-laajennuslomake, jota ei ole vielä muunnettu muulla vastauksella, joka testaa nimenomaisesti shell-muuttujan asettamisen – tarkoitan ${var?not set} – testin läpäisemistä ja selviytymistä varmistaa, että *) case vastaava muuttuja antaa esimerkiksi lopullisen vastauksen.
  • Korjaus – tämä itse asiassa vastaisi vastaamaan alun perin esitettyyn kysymykseen, mutta sitä on sittemmin muokattu siten, että se muuttaa perusteellisesti kysymyksen merkitystä ja mitätöi vastauksesi.
  • Tarvitset [[ $param = *[!\ ]* ]] ryhmässä mksh.

Vastaa

POSIXly:

case $var in (*[![:blank:]]*) echo "$var contains non blank";; (*) echo "$var contains only blanks or is empty or unset" esac 

Erotettavaksi tyhjä , ei-tyhjä , tyhjä , poista :

case ${var+x$var} in (x) echo empty;; ("") echo unset;; (x*[![:blank:]]*) echo non-blank;; (*) echo blank esac 

[:blank:] on tarkoitettu vaakavälimerkkeihin (välilyönti ja sarkain A: ssa SCII, mutta maassasi on todennäköisesti muutama muu; joissakin järjestelmissä on katkeamaton tila (jos käytettävissä), jotkut eivät voittaneet ”t”. Jos haluat myös pystyvälimerkkejä (kuten uusi viiva tai lomakesyöttö), korvaa [:blank:] kanssa [:space:].

Kommentit

  • POSIXly on ihanteellinen, koska se toimii (todennäköisesti parempi) kanssa viiva.
  • zsh näyttää olevan ongelma [![:blank:]] kanssa, se nostaa :b on virheellinen modifikaattori. Kohteissa sh ja ksh jäljitelty, se nostaa tapahtumaa, jota ei löydy ryhmästä [
  • @cuonglm, mitä yritit? var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac' on minulle OK. Tapahtumaa, jota ei löydy, olisi tarkoitettu vain interaktiivisille kuoreille.
  • @St é phaneChazelas: Ah, oikein, yritin interaktiivisilla säikeillä. Virheellinen :b -muunnos on hieman outo.
  • @FranklinYu, käyttöjärjestelmässä / X sh on rakennettu --enable-xpg-echo-default ja --enable-strict-posix-default kanssa siten, että se on Unix-yhteensopiva (johon sisältyy echo '\t' välilehden kirjoittaminen).

Vastaa

Ainoa jäljellä oleva syy kirjoittaa komentosarjan komentosarja hyvällä komentosarjakielellä olevan komentosarjan sijaan on, jos äärimmäinen siirrettävyys on ensisijainen huolenaihe. Vanha /bin/sh on ainoa asia, josta voit olla varma, mutta esimerkiksi Perl on todennäköisemmin käytettävissä useiden alustojen välillä kuin Bash. Älä siis koskaan kirjoita komentosarjoja, jotka käyttävät ominaisuuksia, jotka eivät ole t todella yleismaailmallisia – ja pidä mielessä, että useat Unix-toimittajat jäädyttivät kuoriympäristönsä ennen POSIX.1-2001 .

Tämä testi voidaan tehdä kannettavalla tavalla, mutta sinun on käytettävä tr:

[ "x`printf "%s" "$var" | tr -d "$IFS"`" = x ] 

($IFS: n oletusarvo on kätevästi välilyönti, sarkain ja uusi viiva.)

(printf sisäänrakennettu on itse kannettava, mutta siihen luottaminen on paljon vähemmän vaivaa kuin selvittää, mikä echo -vaihtoehto sinulla on.)

Kommentit

  • Se on ’ vähän sekava.Tavanomainen kannettava tapa testata, sisältääkö merkkijono tiettyjä merkkejä, on ja case .
  • @Gilles En voi ’ uskoa, että ’ on mahdollista kirjoittaa case glob tunnistaa merkkijono, joka on joko tyhjä tai sisältää vain välilyöntejä. (Se olisi helppoa, kun regexp on käytössä, mutta case ei ’ t tee regexpsiä. Vastauksessasi oleva rakenne voitti ’ ei toimi, jos välität uusista viivoista.)
  • Annoin vastauksessani esimerkkejä välilyönneistä, koska ’ s mikä kysymys pyysi. ’ on yhtä helppo testata tyhjät merkit: case $param in *[![:space:]]*) …. Jos haluat testata IFS -merkkejä, voit käyttää mallia *[$IFS]*.
  • @mikeserv Todella vakavasti puolustava komentosarja, määrität IFS: n nimenomaisesti alkuun <space><tab><newline> eikä koskaan kosketa sitä uudelleen. Luulin, että ’ d olisi häiriötekijä.
  • Mitä tulee mallien muuttujiin, mielestäni se toimii kaikissa Bourne-versioissa ja kaikissa POSIX-kuoreissa; se edellyttäisi ylimääräistä koodia tapauskuvioiden havaitsemiseksi ja muuttujan laajennuksen poistamiseksi käytöstä, enkä ’ voi ajatella syytä siihen. Minulla on pari tapausta .profile -palvelussa, jonka monet Bourne-kuoret ovat suorittaneet. Tietysti [$IFS] ei voittanut ’ t sitä, mikä oli tarkoitettu, jos IFS: llä on tiettyjä ei-oletuksia arvot (tyhjät (tai asettamattomat), jotka sisältävät ], alkavat ! tai ^) .

vastaus

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 

kommentit

  • tämä poistaa kaikki välilyönnimerkit, ei vain yhden välilyönnin, eikö? kiitos

vastaus

Jos haluat testata, onko muuttuja tyhjä tai sisältääkö välilyöntejä, voit käyttää myös tätä koodia:

${name:?variable is empty} 

Kommentit

  • Luulen, että vastauksesi on alhainen, koska ” tai sisältää välilyöntejä ” ei ole totta.
  • ole varovainen – se tappaa nykyisen kuoren. Parempi laittaa se a (: $ {subshell?}). Lisäksi – joka kirjoittaa stderr: ään – haluat todennäköisesti ohjata uudelleen. Ja tärkein , joka arvioi muuttujan ’ todellisen arvon, jos se ei ole asetettu tai nolla. Jos siellä on ’ komento, suoritit sen vain. ’ on parasta suorittaa testi testillä :.
  • miten se tappaa kuoren. ja u voi myös testata tämän, määritä ensin name=aaaa ja suorita sitten tämä komento echo ${name:?variable is empty} se tulostaa muuttujan nimen arvon ja suorittaa tämän komennon echo ${name1:?variable is empty} se tulostaa -sh: nimi1: muuttuja on tyhjä
  • kyllä – echo ${name:?variable is empty} joko arvioi $name ’ ei-nolla-arvon tai se tappaa kuoren. Joten samasta syystä et ’ t tee prompt > $randomvar eikä sinun pitäisi ${var?} – jos ’ sa-komento siellä, se ’ todennäköisesti käy – ja et ’ t tiedä mikä se on. Vuorovaikutteisen kuoren ei tarvitse poistua ’ – tästä syystä sinun ei tarvitse ’ t. Silti, jos haluat nähdä joitain testejä, siellä on paljon niitä täällä. . Tämä ei ole ’ t niin kauan …

vastaus

Lähettämäsi koodi [[ ! -z $param ]] && echo "I am not zero" tulostaa I am not zero jos param on joko asetamaton / määrittelemätön tai tyhjä (bash, ksh ja zsh).

Vastaanottajaan myös tulosta, jos param sisältää vain välilyöntejä (poista välilyönnit), POSIXly (laajemmalle kuorialueelle):

 [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

Selitys:

  • A ${param# … } poistaa johtavan tekstin.
  • Tuo johtava teksti on annettu: ${param%%[! ]*}
  • joka laajenee kaikkiin välilyönteihin ennen mikä tahansa muu kuin välilyönti -merkki, ts. Kaikki etualat.

Koko laajennuksen lopputulos on, että kaikki etutilat poistetaan.

Tämä laajennettu tulos testataan, jos pituus on 0.

  • Jos tulos on tyhjä, joko muuttuja oli tyhjä tai
  • poistamalla etutiloja teki sen tyhjäksi.

Jos testi on totta, muuttuja oli joko jo tyhjä tai siinä oli vain välilyöntejä.


Käsite on helppo laajentaa useampaan merkkityypit. Jos haluat sisällyttää myös välilehtiä, sijoita selkeä välilehti hakasulausekkeen sisälle:

 [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

tai käytä muuttujaa poistettavien merkkien kanssa:

 var=$" \t" # in ksh, bash, zsh [ -z "${param#"${param%%[!$var]*}"}" ] && echo "empty" 

tai voit käyttää jotakin POSIX-merkkiluokkalauseketta (tyhjä tarkoittaa välilyöntiä ja välilehteä):

 [ -z "${param#"${param%%[![:blank:]]*}"}" ] && echo "empty" 

vastaus

Tarkistetaan, onko muuttujassa vain välilyöntejä, mukaan lukien monirivinen muuttuja , kokeile tätä:

[[ $var = *[$" \t\n"]* ]] 

Tai xargs:

[[ -z $(echo $var | xargs) ]] 

Tai sedillä:

[[ -z $(sed "/^$/d" <<< $var) ]] 

Vastaa

Kokeile tätä:

$ [[ -z \`echo $n\` ]] && echo zero zero 

Vastaa

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