bash: tesztelje, hogy a $ WORD szerepel-e a

Konstrukciót keresek a bash fájlban, hogy eldöntsem, a $WORD változó a meghatározott szavak egyike. Valami ilyesmire van szükségem:

if "$WORD" in dog cat horse ; then echo yes else echo no fi 

a bash rendelkezik ilyen konstrukcióval? Ha nem, akkor mi lenne a legközelebb?

Válasz

Ez csak Bash (csak = 3. verzió) megoldás, amely reguláris kifejezéseket használ:

if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi 

Ha a szavak listája hosszú, akkor fájlban tárolhatja (soronként egy szót), és ezt tegye:

if [[ "$WORD" =~ $(echo ^\($(paste -sd"|" /your/file)\)$) ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi 

Egy figyelmeztetés a fájl megközelítéssel:

  • Megszakad, ha a fájlban szóköz van. Ezt orvosolhatjuk valamivel:

    sed "s/[[:blank:]]//g" /your/file | paste -sd "|" /dev/stdin 

Köszönöm a @terdon-nak, hogy emlékeztetett arra, hogy megfelelően rögzítsem a mintát a ^ és $.

Megjegyzések

  • És shopt -s nocasematch segíthet, ha azt szeretné, hogy a keresés ne legyen érzékeny a kis- és nagybetűkre.
  • Ne feledje, hogy a [[ és a ]][ és ] nem elég.
  • kerestem egy ‘ onelinerhez ‘, hogy érvényesítse a szkript argumentumomat, és ez tökéletesen működött. köszönöm! [[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
  • Ha ‘ fájlba helyezi a mérkőzések listáját, akkor használhatja is grep: egrep -q "^$WORD$" /tmp/words; [[ $? != 0 ]] && echo "Not found" || echo "OK".

Válasz

case $word in dog|cat|horse) echo yes;; *) echo no;; esac 

Válasz

Mi a helyzet:

#!/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" 

Ezután:

$ a.sh cat cat is in the list $ a.sh bob bob is not in the list 

Válasz

if (echo "$set" | fgrep -q "$WORD") 

Megjegyzések

  • Óvatosan, ez igaz lesz, ha a $WORD üres, akkor megegyezik, ha WORD=ca vagy WORD=og vagy hasonló, és feltételezem, hogy echo ${set[@]} -re gondolt.
  • csak add hozzá -w grepelni a részszavak elkerülése érdekében

Válasz

Ehhez definiálhatsz egy bash függvényt:

function word_valid() { if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then echo no else echo yes fi } 

Ezután egyszerűen így használja:

word_valid cat 

Válasz

“egy soros” megoldást kerestem a szkript-érv érvényesítéséhez, és a fenti Joseph R. választ használtam. a következővel:

[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }

Válasz

Ön az fgrep segítségével megadhatja az összes megengedett szót:

if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then echo yes else echo no fi 

A -w zászló csak teljes szavakkal felel meg, a -q jelző némán működik (mivel csak az if utasítás visszatérési értékére van szükségünk), és minden -e minta megad egy mintát engedélyezése.

fgrep a grep azon verziója, amely normál karakterlánc-egyezést végez a regex-egyezés helyett. Ha van grep, akkor rendelkeznie kell fgrep -vel, de ha nincs, akkor megegyezik a grep a -F zászlóval (tehát a fenti fgrep -wq szöveget kicserélné a következőre: grep -Fwq).

Válasz

Ez nekem bevált:

#!/bin/bash phrase=(cat dog parrot cow horse) findthis=parrot for item in ${phrase[*]} do test "$item" == "$findthis" && { echo "$findthis found!"; break; } done 

Válasz

Érdemes fájlba tenni a szavak listáját, ha gyakran módosítja a listát, vagy ha azt szeretné, hogy több szkript is megoszthatja. És lehet, hogy be kell töltenie a szavakat egy fájlba, ha a lista túl hosszú lesz ahhoz, hogy kezelje egy szkriptben. Ezután mondhatja a következőt:

if fgrep –qx "$WORD" word_list 

Megjegyzések

  • nem, nem akarom, hogy a listám fájlba kerüljön
  • ul ‘ >

Válasz

Ha a szavak egy lista, ahol az értékeket új sor választja el, akkor ezt megteheti:

WORDS="$(ls -1)" if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then echo yes else echo no fi 

Válasz

Nekem ugyanaz a problémám, és meglepően érthető megoldást találtam, amely nem igényel regex ismereteket.

Felhívjuk figyelmét, hogy a Az alábbiakban bemutatott megoldás csak bash lehet, mert fogalmam sincs a bash és más héjak közötti különbségekről. Ezenkívül a bash kézikönyv figyelmeztet arra, hogy ez a fajta mintaillesztés lassú, ha a megfelelő karakterlánc hosszú.

WORD=abc [[ "$WORD" == @(def|abc|ghi|foo|barbaz) ]] && echo Word is in set. 

Hogyan működik ez?Nem a bash kézikönyv nagy részeit akarom itt megismételni, hanem a saját szavaimmal:

Ha az == bináris operátort használjuk az összetett paranccsal [[, az operátor jobb oldalán lévő szó mintaillesztésen megy keresztül, a ” szakaszban leírtak szerint. Mintaillesztés ” a bash kézikönyvben. Továbbá, ilyen feltételek mellett, a párosítás során feltételezzük, hogy a extglob shell opció be van állítva (a tényleges beállítástól függetlenül); a legfontosabb a fentiek megértésében.

De mi van akkor, ha a készlet szavai már tartalmaznak olyan karaktereket, amelyeknek különleges jelentése van a minták illesztésében, a parancsok cseréjében és más kiterjesztésekben? A jogorvoslat egyszerű: Csak használjon valami hasonlót

[[ "$WORD" == @("a*"|abc|"?ghi"|"$DontExpandMe"|barbaz) ]] && echo Word is in set. 

Ezt nagyon könnyűnek, érthetőnek és hatékonynak találtam (amennyiben a $WORD rövid) oldat, amelynek nincs mellékhatása, vagy da ideges, mint például a set alapú módszerek.

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