Come verificare se un file contiene una stringa specifica usando Bash


Risposte:


466
if grep -q SomeString "$File"; then
  Some Actions # SomeString was found
fi

Non hai bisogno di [[ ]]qui. Basta eseguire il comando direttamente. Aggiungi -qun'opzione quando non hai bisogno della stringa visualizzata quando è stata trovata.

Il grepcomando restituisce 0 o 1 nel codice di uscita in base al risultato della ricerca. 0 se è stato trovato qualcosa; 1 altrimenti.

$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0

È possibile specificare i comandi come condizione di if. Se il comando restituisce 0 nel suo codice di uscita significa che la condizione è vera; altrimenti falso.

$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$

Come puoi vedere, esegui qui direttamente i programmi. Nessun ulteriore []o [[]].


Maggiori informazioni grepe opzioni disponibili in asnwer stackoverflow.com/a/4749368/1702557
Pawel

2
potrebbe prendere in considerazione -Fxqparametri come in stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki

3
considerare l'utilizzo -m 1per migliorare le prestazioni di scansione. Restituisce alla prima occorrenza.
AlikElzin-Kilaka

1
se SomeStringcontiene caratteri speciali regex (come .) potresti ottenere risultati inaspettati. È sempre più sicuro usare fgrep(o grep -F) (a meno che non si abbia davvero bisogno di una regex, nel qual caso egrep(o grep -E) è probabilmente la scelta migliore)
Walter Tross,

L'esempio di ifesempio non è corretto, poiché controlla solo se il codice di uscita era diverso da 0. Se si verifica un errore, come il file non può essere letto, anche il codice di uscita è diverso da 0. Quindi devi fare qualcosa di simile ec=$?e controllare se è 0(trovato), quindi se è 1(non trovato) e quindi se è qualcos'altro (fallire).
Ddekany,

40

Oltre ad altre risposte, che ti hanno detto come fare quello che volevi, provo a spiegare cosa non andava (che è quello che volevi.

In Bash, ifdeve essere seguito con un comando. Se il codice di uscita di questo comando è uguale a 0, la thenparte viene eseguita, in elsecaso contrario viene eseguita la parte.

Puoi farlo con qualsiasi comando, come spiegato in altre risposte: if /bin/true; then ...; fi

[[è un comando bash interno dedicato ad alcuni test, come l'esistenza di file, confronti di variabili. Allo stesso modo [è un comando esterno (che si trova in genere in /usr/bin/[) che esegue all'incirca gli stessi test ma ha bisogno ]di un argomento finale, motivo per cui ]deve essere riempito con uno spazio a sinistra, che non è il caso ]].

Qui non è necessario [[[.

Un'altra cosa è il modo in cui citi le cose. In bash, c'è solo un caso in cui nidificano coppie di virgolette "$(command "argument")". Ma in 'grep 'SomeString' $File'te hai solo una parola, perché 'grep 'è un'unità quotata, che viene concatenata SomeStringe quindi nuovamente concatenata ' $File'. La variabile $Filenon viene nemmeno sostituita con il suo valore a causa dell'uso di virgolette singole. Il modo corretto per farlo è grep 'SomeString' "$File".


15

Nel caso in cui si desideri verificare se il file non contiene una stringa specifica, è possibile farlo come segue.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi

10
##To check for a particular  string in a file

cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME  
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi

2
Cambiare directory di solito non è una buona idea (ed è del tutto superfluo qui, basta qualificare il nome file con la directory di destinazione). E poi quello che hai è esattamente la stessa cosa della risposta accettata, solo con meno dettagli.
Mat

Grazie per il consiglio Mat
Nevin Raj Victor,

7

Versione più corta (corretta):

grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"

può anche essere scritto come

grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"

ma non è necessario testarlo esplicitamente in questo caso, quindi lo stesso con:

grep -q "something" file && echo "yes" || echo "no"

3
if grep -q something file; then echo yes; else echo no; fi. Nessun motivo per scherzare $?affatto.
Charles Duffy,

6

Nel caso in cui si desideri verificare se la stringa corrisponde all'intera riga e se si tratta di una stringa fissa, è possibile farlo in questo modo

grep -Fxq [String] [filePath]

esempio

 searchString="Hello World"
 file="./test.log"
 if grep -Fxq "$searchString" $file
    then
            echo "String found in $file"
    else
            echo "String not found in $file"
 fi

Dal file man:

-F, --fixed-strings

          Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of 

which is to be matched.
          (-F is specified by POSIX.)
-x, --line-regexp
          Select only those matches that exactly match the whole line.  (-x is specified by 

POSIX.)
-q, --quiet, --silent
          Quiet; do not write anything to standard output.  Exit immediately with zero 

status  if  any  match  is
          found,  even  if  an error was detected.  Also see the -s or --no-messages 

option.  (-q is specified by
          POSIX.)

6
grep -q [PATTERN] [FILE] && echo $?

Lo stato di uscita è 0(vero) se il modello è stato trovato; altrimenti cordoncino.


4
if grep -q [string] [filename]
then
    [whatever action]
fi

Esempio

if grep -q 'my cat is in a tree' /tmp/cat.txt
then
    mkdir cat
fi

2

Prova questo:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi

3
Mi sto esitando in modo esagerato dal sottovalutare questo, ma Stack Overflow non dovrebbe perpetuare questo tipo di logica pretzel. greprestituisce uno stato di uscita per un'ottima ragione; catturare l'output in una stringa potenzialmente memorizzerà una grande quantità di testo in un buffer solo per poter dire che non è vuoto.
Tripleee


-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"

1
Hai un refuso -!? dovrebbe essere $?
lzap

... non solo è destinato a esserlo $?, ma non ce n'è bisogno - potresti semplicemente farloif grep -q ...
Charles Duffy,

1
Inoltre, foo && truthy_action || falsey_actionnon è un vero operatore ternario - se truthy_actionfallisce, falsey_actionviene eseguito anche in aggiunta .
Charles Duffy,

Più in generale, lo scopo di ifè eseguire un comando e verificarne il codice di uscita. Molto raramente dovresti esaminare $?esplicitamente.
Tripleee
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.