So überprüfen Sie mithilfe von Bash, ob eine Datei eine bestimmte Zeichenfolge enthält

Antworten:

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

Du brauchst [[ ]]hier nicht. Führen Sie den Befehl einfach direkt aus. -qOption hinzufügen, wenn die Zeichenfolge nicht angezeigt werden muss, als sie gefunden wurde.

Der grepBefehl gibt je nach Suchergebnis 0 oder 1 im Exit-Code zurück. 0 wenn etwas gefunden wurde; 1 sonst.

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

Sie können Befehle als Bedingung für angeben if. Wenn der Befehl in seinem Exitcode 0 zurückgibt, bedeutet dies, dass die Bedingung erfüllt ist. sonst falsch.

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

Wie Sie sehen, führen Sie hier die Programme direkt aus. Keine zusätzlichen []oder [[]].

Igor Chubin
quelle
Weitere Informationen grepund verfügbare Optionen finden Sie unter asnwer stackoverflow.com/a/4749368/1702557
Pawel,
2
Vielleicht möchten Sie -FxqParameter wie in stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki
3
Erwägen Sie die Verwendung -m 1, um die Scanleistung zu verbessern. Gibt beim ersten Auftreten zurück.
AlikElzin-Kilaka
1
Wenn SomeStringRegex-Sonderzeichen (wie .) enthalten sind, erhalten Sie möglicherweise unerwartete Ergebnisse. Es ist sicherer, immer fgrep(oder grep -F) zu verwenden (es sei denn, Sie benötigen wirklich einen regulären Ausdruck. In diesem Fall ist egrep(oder grep -E) wahrscheinlich die beste Wahl)
Walter Tross
Das Beispielbeispiel ifist falsch, da nur geprüft wird, ob der Exit-Code nicht 0 war. Wenn ein Fehler auftritt, z. B. dass die Datei nicht gelesen werden kann, ist der Exit-Code ebenfalls ungleich 0. Sie müssen also so etwas tun ec=$?und prüfen, ob es 0(gefunden) ist, ob es 1(nicht gefunden) ist und ob es etwas anderes ist (fehlschlagen).
ddekany
40

Neben anderen Antworten, die Ihnen sagten, wie Sie tun sollen, was Sie wollten, versuche ich zu erklären, was falsch war (was Sie wollten.

In Bash ifsoll ein Befehl folgen. Wenn der Exit-Code dieses Befehls gleich 0 ist, wird das thenTeil ausgeführt, andernfalls wird das elseTeil ausgeführt, falls vorhanden.

Sie können dies mit jedem Befehl tun, wie in anderen Antworten erläutert: if /bin/true; then ...; fi

[[ist ein interner Bash-Befehl, der einigen Tests gewidmet ist, z. B. dem Vorhandensein von Dateien und Variablenvergleichen. In ähnlicher Weise [handelt es sich um einen externen Befehl (der sich normalerweise in befindet /usr/bin/[), der ungefähr dieselben Tests ausführt, jedoch ]als letztes Argument benötigt wird, weshalb er ]mit einem Leerzeichen auf der linken Seite aufgefüllt werden muss, was bei nicht der Fall ist ]].

Hier müssen Sie nicht [[noch [.

Eine andere Sache ist die Art und Weise, wie Sie Dinge zitieren. In Bash gibt es nur einen Fall, in dem Anführungszeichenpaare verschachtelt sind "$(command "argument")". Aber in 'grep 'SomeString' $File'dir hast du nur ein Wort, denn es 'grep 'ist eine zitierte Einheit, die mit verkettet SomeStringund dann wieder verkettet wird ' $File'. Die Variable $Filewird aufgrund der Verwendung von einfachen Anführungszeichen nicht einmal durch ihren Wert ersetzt. Der richtige Weg, das zu tun, ist grep 'SomeString' "$File".

Benoit
quelle
15

Im Fall , wenn Sie möchten , zu überprüfen , ob Datei nicht nicht eine bestimmte Zeichenfolge enthält, können Sie tun , es folgt wie.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi
Lahiru Chandima
quelle
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
Nevin Raj Victor
quelle
2
Ein Verzeichniswechsel ist normalerweise keine gute Idee (und hier völlig unnötig, qualifizieren Sie einfach den Dateinamen mit dem Zielverzeichnis). Und was Sie dann haben, ist genau das Gleiche wie die akzeptierte Antwort, nur mit weniger Details.
Mat
Vielen Dank für den Rat Mat
Nevin Raj Victor
7

Kürzeste (richtige) Version:

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

kann auch geschrieben werden als

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

In diesem Fall müssen Sie es jedoch nicht explizit testen.

grep -q "something" file && echo "yes" || echo "no"
lzap
quelle
3
if grep -q something file; then echo yes; else echo no; fi. Kein Grund, sich überhaupt anzulegen $?.
Charles Duffy
6

Wenn Sie überprüfen möchten, ob die Zeichenfolge mit der gesamten Zeile übereinstimmt und ob es sich um eine feste Zeichenfolge handelt, können Sie dies auf diese Weise tun

grep -Fxq [String] [filePath]

Beispiel

 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

Aus der Man-Datei:

-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.)
Shubham Khatri
quelle
6
grep -q [PATTERN] [FILE] && echo $?

Der Exit-Status ist 0(true), wenn das Muster gefunden wurde. sonst blankstring.

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

Beispiel

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

Versuche dies:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi
vgokul129
quelle
3
Ich verzichte zögernd darauf, dies abzulehnen, aber Stack Overflow sollte diese Art von Brezel-Logik nicht aufrechterhalten. grepgibt aus einem sehr guten Grund einen Exit-Status zurück; Durch das Erfassen der Ausgabe in einer Zeichenfolge wird möglicherweise eine große Menge Text in einem Puffer gespeichert, sodass Sie sagen können, dass er nicht leer ist.
Tripleee
-1

Ich habe das getan, scheint gut zu funktionieren

if grep $SearchTerm $FileToSearch; then
   echo "$SearchTerm found OK"
else
   echo "$SearchTerm not found"
fi
Madarekrap
quelle
Das Zitat ist fehlerhaft und Sie möchten wahrscheinlich vermeiden, dass die Ausgabe von angezeigt wirdgrep .
Tripleee
-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
chemila
quelle
1
Du hast einen Tippfehler - !? soll $ sein?
lzap
... es ist nicht nur beabsichtigt $?, es ist überhaupt nicht nötig - Sie könnten es einfach tunif grep -q ...
Charles Duffy
1
Außerdem foo && truthy_action || falsey_actionist es kein echter ternärer Operator - wenn er truthy_actionausfällt, falsey_actionwird er zusätzlich ausgeführt .
Charles Duffy
Im Allgemeinen besteht der Zweck von ifdarin, einen Befehl auszuführen und seinen Exit-Code zu überprüfen. Sie sollten sehr selten $?explizit prüfen müssen .
Tripleee