Ich möchte überprüfen, ob eine Datei eine bestimmte Zeichenfolge enthält oder nicht. Ich habe dieses Skript verwendet, aber es funktioniert nicht:
if [[ 'grep 'SomeString' $File' ]];then
# Some Actions
fi
Was ist falsch in meinem Code?
Ich möchte überprüfen, ob eine Datei eine bestimmte Zeichenfolge enthält oder nicht. Ich habe dieses Skript verwendet, aber es funktioniert nicht:
if [[ 'grep 'SomeString' $File' ]];then
# Some Actions
fi
Was ist falsch in meinem Code?
Antworten:
if grep -q SomeString "$File"; then
Some Actions # SomeString was found
fi
Du brauchst [[ ]]
hier nicht. Führen Sie den Befehl einfach direkt aus. -q
Option hinzufügen, wenn die Zeichenfolge nicht angezeigt werden muss, als sie gefunden wurde.
Der grep
Befehl 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 [[]]
.
grep
und verfügbare Optionen finden Sie unter asnwer stackoverflow.com/a/4749368/1702557
-Fxq
Parameter wie in stackoverflow.com/a/4749368/544721
-m 1
, um die Scanleistung zu verbessern. Gibt beim ersten Auftreten zurück.
SomeString
Regex-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)
if
ist 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).
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 if
soll ein Befehl folgen. Wenn der Exit-Code dieses Befehls gleich 0 ist, wird das then
Teil ausgeführt, andernfalls wird das else
Teil 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 SomeString
und dann wieder verkettet wird ' $File'
. Die Variable $File
wird aufgrund der Verwendung von einfachen Anführungszeichen nicht einmal durch ihren Wert ersetzt. Der richtige Weg, das zu tun, ist grep 'SomeString' "$File"
.
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
##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
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"
if grep -q something file; then echo yes; else echo no; fi
. Kein Grund, sich überhaupt anzulegen $?
.
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.)
grep -q [PATTERN] [FILE] && echo $?
Der Exit-Status ist 0
(true), wenn das Muster gefunden wurde. sonst blankstring.
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
Versuche dies:
if [[ $(grep "SomeString" $File) ]] ; then
echo "Found"
else
echo "Not Found"
fi
grep
gibt 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.
Ich habe das getan, scheint gut zu funktionieren
if grep $SearchTerm $FileToSearch; then
echo "$SearchTerm found OK"
else
echo "$SearchTerm not found"
fi
grep
.
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
$?
, es ist überhaupt nicht nötig - Sie könnten es einfach tunif grep -q ...
foo && truthy_action || falsey_action
ist es kein echter ternärer Operator - wenn er truthy_action
ausfällt, falsey_action
wird er zusätzlich ausgeführt .
if
darin, einen Befehl auszuführen und seinen Exit-Code zu überprüfen. Sie sollten sehr selten $?
explizit prüfen müssen .