Was ist der Unterschied zwischen der grep-Apfeldatei und der grep-Apfeldatei?

22

Was ist der Unterschied zwischen grep apple fileund grep "apple" file? Was bewirkt das Setzen der Anführungszeichen? Sie scheinen beide zu funktionieren und tun genau dasselbe (dieselbe Zeile anzeigen).

John Stacen
quelle

Antworten:

45

Die Anführungszeichen wirken sich darauf aus, welche Zeichen Ihre Shell als besonders betrachtet und welche syntaktische Bedeutung sie hat. In Ihrem Beispiel macht dies keinen Unterschied, da applekeine solchen Zeichen enthalten sind.

Betrachten Sie jedoch ein anderes Beispiel: grep apple tree fileSucht nach dem Wort applein den Dateien treeund file, während grep "apple tree" filedas Wort apple treein der Datei gesucht wird file. Die Anführungszeichen weisen bash darauf hin, dass das Wort Leerzeichen in "apple tree"keinem neuen Parameter beginnt, sondern Teil des aktuellen Parameters sein soll. grep apple\ tree filewürde das gleiche Ergebnis erzielen, da \bash anweist, die spezielle Bedeutung des folgenden Zeichens zu ignorieren und es wörtlich zu behandeln.

David Foerster
quelle
2
Dies ist auch bei Platzhaltern sichtbar. Wenn Sie dies tun grep a*b equations.txt, wird gesucht a*b, es sei denn, es befindet sich eine Datei im aktuellen Verzeichnis, die mit a beginnt und mit b endet. In diesem Fall (da (ba) sh die Dateinamen in der Befehlszeile erweitert) wird grep mit aufgerufen Vervollständigen Sie unterschiedliche Parameter, was zu unterschiedlichen Ergebnissen führt. Dies ist normalerweise eher ein Problem bei der Suche, da ein Befehl wie find . -name *.txtder zu unerwartetem Verhalten führt, wenn sich im aktuellen Verzeichnis eine txt-Datei befindet. In diesem Fall ist es besser, Anführungszeichen zu verwenden.
SztupY
4
Ein weiterer wichtiger Punkt ist der Unterschied zwischen Anführungszeichen ( ") und einfachen Anführungszeichen ( '). Einfache Anführungszeichen verhindern die Interpretation bestimmter Zeichen $, während doppelte Anführungszeichen die Interpretation ermöglichen. ZB grep '${USER}'wird nach dem Text ${USER}gesucht, wohingegen grep "${USER}"nach dem Text, den die Variable USERenthält (zB johnstacen).
Paddy Landau
23

Doppelte Anführungszeichen erlauben die Auswertung, einfache Anführungszeichen verhindern die Auswertung, keine Anführungszeichen erlauben die Erweiterung mit Platzhaltern, wenn sie in der Befehlszeile verwendet werden. Als erfundene Beispiele:

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

Das Verständnis der Funktionsweise von Zitaten ist entscheidend für das Verständnis von Bash. Beispielsweise:

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

Sie können einfache Anführungszeichen verwenden, um einen Befehl über eine Variable zu übergeben. Einfache Anführungszeichen verhindern die Bewertung. Doppelte Anführungszeichen werden ausgewertet.

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

Sie können einfache Anführungszeichen in doppelten Anführungszeichen und doppelte Anführungszeichen in doppelten Anführungszeichen verwenden. Doppelte Anführungszeichen in einfachen Anführungszeichen dürfen jedoch nicht verwendet werden (ohne sie zu maskieren). Sie werden wörtlich interpretiert. Einfache Anführungszeichen in einfachen Anführungszeichen sollten nicht gemacht werden (ohne sie zu verlassen).

Um Bash effektiv nutzen zu können, müssen Sie ein gründliches Verständnis der Anführungszeichen haben. Sehr wichtig!

Im Allgemeinen verwende ich keine Anführungszeichen, wenn Bash Elemente (z. B. ein Array) erweitern soll, ich verwende einfache Anführungszeichen für Zeichenfolgen, die nicht geändert werden dürfen, und ich verwende doppelte Anführungszeichen für Variablen das sind wahrscheinlich jede Art von Zeichenfolge zurück. Damit soll sichergestellt werden, dass Leerzeichen und Sonderzeichen erhalten bleiben.

AsymLabs
quelle
Wie würden Sie doppelte Anführungszeichen in Anführungszeichen verwenden? Ist das ein Tippfehler? Und warum sollte ich stattdessen doppelte Anführungszeichen in einfache Anführungszeichen setzen? Vermutlich haben Sie die Sätze vertauscht?
Byte Commander
@ByteCommander Ja, das Konzept doppelter Anführungszeichen in doppelten Anführungszeichen wird häufig verwendet. In diesem Beitrag finden Sie ein prominentes Arbeitsbeispiel. In der Regel werden Zeichenfolgen geschützt, die Leerzeichen enthalten, häufig in Bezug auf Pfadzeichenfolgen. Doppelte Anführungszeichen können in einfachen Anführungszeichen mit oder ohne Escape-Zeichen verwendet werden, werden jedoch wörtlich interpretiert, dh sie führen nicht zu einer Bewertung. Ich werde diesen Punkt in der Post klären.
AsymLabs