Etsin rakennetta bash
, päättää onko muuttuja $WORD
on määriteltyjä sanoja. Tarvitsen jotain tällaista:
if "$WORD" in dog cat horse ; then echo yes else echo no fi
onko bashilla tällainen rakenne? Jos ei, mikä olisi lähin?
Vastaus
Tämä on vain Bash-ratkaisu (> = versio 3), joka käyttää säännöllisiä lausekkeita:
if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi
Jos sanaluettelosi on pitkä, voit tallentaa sen tiedostoon (yksi sana riviä kohden) ja tehdä näin:
if [[ "$WORD" =~ $(echo ^\($(paste -sd"|" /your/file)\)$) ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi
Yksi varoitus tiedostotavalla:
-
Se rikkoo, jos tiedostossa on tyhjää tilaa. Tämä voidaan korjata esimerkiksi:
sed "s/[[:blank:]]//g" /your/file | paste -sd "|" /dev/stdin
Kiitos @terdonille, joka muistutti minua kiinnittämään kuvio oikein ^
ja $
.
Kommentit
Vastaa
case $word in dog|cat|horse) echo yes;; *) echo no;; esac
Vastaus
Entä:
#!/usr/bin/env bash WORD="$1" for w in dog cat horse do if [ "$w" == "$WORD" ] then yes=1 break fi done; [ "$yes" == "1" ] && echo "$WORD is in the list" || echo "$WORD is not in the list"
Sitten:
$ a.sh cat cat is in the list $ a.sh bob bob is not in the list
vastaus
if (echo "$set" | fgrep -q "$WORD")
Kommentit
- Huolellisesti, tämä palauttaa arvon tosi, jos
$WORD
on tyhjä, se vastaa, josWORD=ca
taiWORD=og
tai vastaavaa, ja oletan, että tarkoititecho ${set[@]}
. - lisää vain -w grepiin osittaisten sanojen välttämiseksi
Vastaus
Voit määrittää tälle bash-funktion:
function word_valid() { if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then echo no else echo yes fi }
Käytä sitten yksinkertaisesti näin:
word_valid cat
Vastaa
Etsin ”yksi rivi” -ratkaisua skripti-argumenttini vahvistamiseksi ja käytin yllä olevaa Joseph R. -vastausta . ylöspäin:
[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
Vastaa
Sinä voisi käyttää fgrep-tiedostoa kaikkien sallittujen sanojen määrittämiseen:
if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then echo yes else echo no fi
Lippu -w
vastaa vain kokonaisia sanoja, -q
-lippu saa sen toimimaan äänettömästi (koska tarvitsemme vain if-käskyn palautusarvon), ja jokainen -e
-malli määrittää mallin sallia.
fgrep
on grep-versio, joka suorittaa normaalin merkkijonovastaavuuden regex-vastaavuuden sijaan. Jos sinulla on grep
, sinulla pitäisi olla fgrep
, mutta jos ei, se on identtinen grep
-F
-lipulla (joten korvaisit yllä olevan fgrep -wq
vain grep -Fwq
).
Vastaus
Tämä toimi minulle:
#!/bin/bash phrase=(cat dog parrot cow horse) findthis=parrot for item in ${phrase[*]} do test "$item" == "$findthis" && { echo "$findthis found!"; break; } done
Vastaa
Voit lisätä sanaluettelon tiedostoon, jos muutat luetteloa usein tai haluat sen jakaa useita komentosarjoja. Ja sinun on ehkä laitettava sanat tiedostoon, jos luettelon hallinta on liian pitkä hallita komentosarjassa. Sitten voit sanoa
if fgrep –qx "$WORD" word_list
Kommentit
- ei, en halua ’ halua luetteloni olevan tiedostossa
Vastaa
Jos sanat ovat luettelo, jossa arvot erotetaan uudella rivillä, voit tehdä seuraavaa:
WORDS="$(ls -1)" if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then echo yes else echo no fi
Vastaus
Minulla oli juuri sama ongelma ja löysin yllättävän ymmärrettävän ratkaisun, joka ei vaadi regex-tuntemusta.
Huomaa, että alla esitetty ratkaisu saattaa olla vain bash, koska minulla ei ole aavistustakaan bashin ja muiden kuorien välisistä eroista. Lisäksi bash-käsikirja varoittaa, että tällainen kuvion sovitus on hidasta, jos vastaava merkkijono on pitkä.
WORD=abc [[ "$WORD" == @(def|abc|ghi|foo|barbaz) ]] && echo Word is in set.
Kuinka tämä toimii?En halua toistaa tässä suuria osia bash-käsikirjasta, mutta omin sanoin:
Jos binaarioperaattoria ==
käytetään yhdistekomennon kanssa [[
, operaattorin oikealla puolella olevalle sanalle tehdään kuvien sovitus, kuten osiossa ” kuvataan ” bash-käsikirjassa. Lisäksi näissä olosuhteissa, kun sovitetaan, kuorivaihtoehdon extglob
oletetaan olevan asetettu (todellisesta asetuksesta riippumatta); tämä on avainasemassa yllä olevan ymmärtämisessä.
Mutta entä jos joukossasi olevat sanat sisältävät jo merkkejä, joilla on erityinen merkitys mallien sovituksessa, komentojen korvaamisessa ja muissa laajennuksissa? Korjauskeino on helppoa: Käytä vain jotain
[[ "$WORD" == @("a*"|abc|"?ghi"|"$DontExpandMe"|barbaz) ]] && echo Word is in set.
Minusta tämä oli erittäin helppoa, ymmärrettävää ja tehokasta (kunhan $WORD
on lyhyt) liuos, jolla ei ole sivuvaikutuksia tai joka on da epämiellyttäviä kuten set
-pohjaiset menetelmät.
shopt -s nocasematch
voi auttaa, jos haluat haun olevan kirjainkoko.[[
ja]]
–[
ja]
eivät riitä.[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
egrep -q "^$WORD$" /tmp/words; [[ $? != 0 ]] && echo "Not found" || echo "OK"
.