Seltsames Verhalten von „ls -a | grep ^ \. ”

10

Ich wollte den Inhalt eines pwd auflisten und nur Dateien anzeigen, die mit dot beginnen. Ich habe es versucht, ls -a | grep ^\.aber ich kann nicht herausfinden, warum die Ausgabe auch die Dateien enthält, die nicht mit Punkt beginnen. Beispielsweise:

Pictures
.pip
.pki
.profile
projects
Public

Ich weiß, dass ich erreichen kann, was ich will. ls -ld .*Ich bin nur neugierig auf dieses Verhalten von grep, das ich nicht erklären kann.

ps-aux
quelle
Warum nicht einfach ls -d .*alle Dateien auflisten, die mit beginnen .?
Barmar
Ein Warnhinweis: Leiten Sie niemals die Ausgabe von ls an einen anderen Befehl weiter. Verwenden Sie stattdessen find. Es gibt viel zu viele Ideosynkrasien, als dass man ihnen vertrauen könnte. Siehe: Fallstricke 1 unter mywiki.wooledge.org/BashPitfalls - es hat # 1 gemacht! Der Rest der Seite ist auch großartig.
Joe

Antworten:

20

Zitieren Sie das Argument grepalsols -a | grep '^\.'

Der Grund dafür ist, dass die Shell sie verarbeitet \.und wieder in eine einfache Form umwandelt ., die grepdann als Platzhalter mit einem Zeichen behandelt wird. Geben Sie im Zweifelsfall immer eine Zeichenfolge an, die ein für die Shell spezielles Zeichen enthält (oder enthalten könnte).

Roaima
quelle
Warum ignoriert Shell \?
ps-aux
\ ist eine Escape-Sequenz, mit der die Shell das folgende Zeichen als wörtliches Zeichen behandelt. In diesem grep ^\\.Fall wird \\ von der Shell als einzelner Backslash behandelt, und der Grep behandelt erneut einen einzelnen Backslash, gefolgt vom Punkt als Literalpunkt.
Avinash Raj
11

Sie müssen den Grep-Regex in Anführungszeichen setzen.

ls -a | grep '^\.'

Hinweis: Analysieren Sie die lsBefehlsausgabe nicht .

Avinash Raj
quelle
Warum ist es schlecht, die Ausgabe von ls zu analysieren?
ps-aux
Über den Link: Wenn die Standardausgabe im Standardmodus kein Terminal ist, trennt ls Dateinamen durch Zeilenumbrüche. Dies ist in Ordnung, bis Sie eine Datei mit einem Zeilenumbruch im Namen haben.
Michael Durrant
@ Michael Durrant: Ich würde vorschlagen, dass das Zulassen von Zeilenumbrüchen in Dateinamen ein großer Systemfehler ist.
Jamesqf
@jamesqf - siehe Zeilenumbrüche in Dateinamen (insbesondere die Antwort von sml ).
don_crissti
0

Wenn Sie cmd ls -a | ausführen grep ^ \. dann betrachte grep "\" nicht als Sonderzeichen und Bedeutung von "." entkomme nicht.

Wenn wir cmd ls -a | verwenden grep "^ \." dann betrachtet grep "\" als Sonderzeichen und Bedeutung von "." wird entkommen. Sie erhalten erwartungsgemäß ein Ergebnis.

Wenn Sie grep cmd ohne Anführungszeichen verwenden möchten, sollten Sie auch das Zeichen "\" maskieren. Sie können das erwartete Ergebnis ohne doppelte Anführungszeichen erzielen, indem Sie den folgenden Befehl ausführen. ls -a | grep ^ \\.

Einzelheiten zur Bedeutung von Sonderzeichen in Regex finden Sie unter folgendem Link. http://www.regular-expressions.info/quickstart.html

AVJ
quelle