bash: verifica se $ WORD è impostato


54

Sto cercando un costrutto bash, per decidere se una variabile $WORDè una delle parole definite. Ho bisogno di qualcosa del genere:

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

bash ha un tale costrutto? In caso contrario, quale sarebbe il più vicino?

Risposte:


57

Questa è una soluzione solo Bash (> = versione 3) che utilizza espressioni regolari:

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

Se l'elenco di parole è lungo, puoi memorizzarlo in un file (una parola per riga) e procedere come segue:

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

Un avvertimento con l'approccio file:

  • Si interromperà se il file ha spazi bianchi. Questo può essere risolto da qualcosa come:

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

Grazie a @terdon per avermi ricordato di ancorare correttamente il modello con ^e $.


1
E shopt -s nocasematchpotrebbe essere utile se si desidera che la ricerca non faccia distinzione tra maiuscole e minuscole.
Skippy le Grand Gourou,

1
Nota che devi usare [[e ]]- [e ]non sono abbastanza.
Greg Dubicki,

stavo cercando un "oneliner" per convalidare la mia tesi di sceneggiatura, e questo ha funzionato perfettamente. grazie! [[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
RASG,


11

Che ne dite di:

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

Poi:

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

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

1
Attento però, questo tornerà vero se $WORDè vuoto, corrisponderà a se WORD=cao WORD=ogo simile e presumo tu intendessi echo ${set[@]}.
terdon

basta aggiungere -w a grep per evitare parole parziali
BrenoZan

1

È possibile definire una funzione bash per questo:

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

Quindi utilizzare semplicemente in questo modo:

word_valid cat

1

stavo cercando una soluzione "a una riga" per convalidare la mia tesi di script, e ho usato la risposta di Joseph R. sopra per trovare:

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


0

Questo ha funzionato per me:

#!/bin/bash
phrase=(cat dog parrot cow horse)
findthis=parrot

for item in ${phrase[*]}
do
    test "$item" == "$findthis" && { echo "$findthis found!"; break; }
done

0

È possibile che si desideri inserire l'elenco di parole in un file, nel caso in cui si cambi spesso l'elenco o si desideri che sia condiviso da più script. E potrebbe essere necessario inserire le parole in un file se l'elenco diventa troppo lungo per essere gestito in uno script. Allora puoi dire

if fgrep qx "$WORD" word_list

no, non voglio avere la mia lista in un file
Martin Vegter,

0

Se le parole sono un elenco in cui i valori sono separati da una nuova riga, puoi fare:

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

0

Puoi usare fgrep per specificare tutte le parole consentite:

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

Il -wflag corrisponde solo a parole intere, il -qflag lo fa funzionare in silenzio (perché tutto ciò di cui abbiamo bisogno è il valore di ritorno per l'istruzione if da usare) e ogni -emodello specifica un modello da consentire.

fgrepè la versione di grep che esegue la normale corrispondenza delle stringhe invece della corrispondenza regex. Se hai grep, dovresti fgrep, ma in caso contrario, è identico all'utilizzo grepcon la -Fbandiera (quindi dovresti semplicemente sostituire fgrep -wqsopra con grep -Fwq).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.