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
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, haWORD=ca
vagyWORD=og
vagy hasonló, és feltételezem, hogyecho ${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.
shopt -s nocasematch
segíthet, ha azt szeretné, hogy a keresés ne legyen érzékeny a kis- és nagybetűkre.[[
és a]]
–[
és]
nem elég.[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
egrep -q "^$WORD$" /tmp/words; [[ $? != 0 ]] && echo "Not found" || echo "OK"
.