2016-05-29 10 views
-4

wenn ich ls tun die Ausgabe lautet: enter image description hereWarum ls | grep * zeigt nichts an?

aber wenn ich tun ls | grep Komplex * oder ll | grep complex* oder sogar ll | grep * oder ll | grep * | less der Ausgang ist immer: enter image description here

Dies ist verwirrend für mich. Ich möchte eine Liste aller Dateien erhalten, die mit complex* beginnen.

+2

Weil die Shell '*' erweitert. Wenn Sie eine Liste aller Dateien erhalten möchten, die mit 'complex *' beginnen, wäre das 'ls complex *'. –

+0

Fügen Sie ein 'echo' ein, um zu sehen, was bash mit Ihrem zweiten Befehl macht:' ls | echo grep * ' – Cyrus

+0

Schlechter, wenn' complex_assignment_other.c' Datei enthält eine Zeile mit dem Ausdruck 'complex_assignment.c', (sagen Sie' // diese Funktion ist in der Datei complex_assignment.c' definiert) wird diese Zeile am Terminal gedruckt .. – anishsane

Antwort

1

Standardmäßig ist * für [ globbing ] gedacht.

Wenn Sie eine Datei mit dem Namen * oder ein * enthält, könnten Sie

tun
ls | grep \* 

oder

ls | grep '*' 

Wenn Sie wörtliche * in den Dateien suchen Sie tun können:

grep '*' * # second will glob all the files in the current dir. 

Wenn Sie alle verwenden möchten die Dateien, die das Wort Complex _plus_something tun haben:

grep -E '\<Complex[_[:alnum:]]+' * 

Hier die + ist für eine oder mehr und \< am Anfang eines Wortes der leere Zeichenkette passen :-)

+0

yeah thanks a lot Ich habe die Anführungszeichen verpasst – hungryWolf

+0

Das abschließende'. * 'Im letzten Beispiel ist völlig überflüssig; Siehe meine Antwort für eine detaillierte Erklärung. – tripleee

+0

okay, danke mann – hungryWolf

3

Sie suchen für:

ls | grep 'complex.*' 

oder besser:

ls complex* 
+0

Vielen Dank Karte, Was für ein Dummy-Fehler: p – hungryWolf

+0

Ich denke, jeder hat fast genau diesen Fehler gemacht ein- oder zweimal;) – webb

1

Um meine Erklärung zu vereinfachen, werde ich nicht über die versteckten Dateien sprechen.

Weil Ihr Befehl nicht das bedeutet, was Sie erreichen möchten.

Das * ist sehr speziell für Bash und hat nicht die Bedeutung, die Sie denken. Es ist ein Zeichen, das die Shell mit allen Dateinamen ersetzt, denen sie im aktuellen Verzeichnis entsprechen kann. Ein Beispiel:

[email protected]:~/foo$ ls 
[email protected]:~/foo$ touch foo 
[email protected]:~/foo$ ls 
foo 
[email protected]:~/foo$ ls | grep * 
foo 

% über dem entspricht $ ls | grep foo

[email protected]:~/foo$ touch bar 
[email protected]:~/foo$ ls | grep * 

% Die obige entspricht $ ls | grep bar foo, gibt er etwas, wenn das Wort "bar" ist IN der Datei foo.

siehe da, ein Beispiel mit mehreren Dateien:

[email protected]:~/foo$ touch bar foo foobar 
[email protected]:~/foo$ echo "bar" > foo 
[email protected]:~/foo$ echo "bar" > foobar 
[email protected]:~/foo$ ls | grep * 
foo:bar 
foobar:bar 

, jetzt zu tun, was Sie * zu Ihrem Vorteil nutzen, können Sie erreichen wollen:

[email protected]:~/foo$ ls foo* 
foo foobar 

Aber wenn es ist ein Verzeichnis, das Ihrer Forschung entspricht, es wird seinen Inhalt auflisten.

[email protected]:~/foo$ mkdir foodir 
[email protected]:~/foo$ for i in {0..10}; do touch "foodir/$i"; done 
[email protected]:~/foo$ ls foo* 
foo foobar 

foodir: 
0 1 10 2 3 4 5 6 7 8 9 

So können Sie die Option verwenden -d dessen Inhalt nicht zur Liste:

[email protected]:~/foo$ ls -d foo* 
foo foobar foodir 

Aber wenn Ihre Suche komplizierter wird, kann ich nur Rat ein leistungsfähigeres Werkzeug zu benutzen, wie zum Beispiel finden.

Dieses verwendet Globbing (die * I oben erläutert)

[email protected]:~/foo$ find . -type f -name "foo*" 
./foo 
./foobar 

Dieses verwendet regulären Ausdruck, aber das ist ein Werkzeug, das Sie brauchen ein bisschen studieren zu können, ohne dabei die Haare behandeln:

[email protected]:~/foo$ find . -type f -regex ".*/foo[^/]*$" 
./foo 
./foobar 

ein wenig zu erklären, suchen die oben das aktuelle Verzeichnis (.) für Dateien nur (Typ f), die ein bestimmtes Muster entspricht (-regex "/foo [^ /] $").

Dieses Muster ist "alles gefolgt von Schrägstrich foo gefolgt von allem außer Schrägstrich bis zum Ende der Datei".

+0

haha! schön abt die Haare: D – hungryWolf

+0

und nette Erklärung zu. Vielen Dank für Ihre Mühe. – hungryWolf

1

Sie haben zwei Fehler: * bedeutet nicht "irgendetwas" in regulären Ausdrücken, und weil Sie es nicht zitiert haben, hat die Shell es erweitert.

Wenn Sie drei Dateien haben, ist das Ergebnis der ls | grep * nach Wildcard-Expansion etwas wie

ls | grep bar baz foo 

Das Verhalten von grep in dieser Situation ist, dass sie ignoriert einfach die Standardeingabe (dies ist nicht dokumentiert werden kann und/oder vollständig Standard und/oder gut definiert), so ls | wird ignoriert und nutzlos. Sie suchen nach dem Namen der ersten passenden Datei in den anderen beiden.

Nun Sie die Suche mit regulären Ausdrücken verwendet für comple überall in den Eingang (x* bedeutet null oder mehr Vorkommen von x, wenn es Null sind, wird der Ausdruck übereinstimmen, und es verhindert nicht, passend auf, sagen wir, incomplete , so könnte man dies weglassen). Der korrekte Ausdruck ist ^complex, um dieses Wort nur am Anfang der Zeile zu finden (nicht die Anführungszeichen zu vergessen; ^ ist auch ein Shell-Metazeichen) oder nur complex, um es überall in einer Zeile zu finden.

Wenn der Punkt nur zum Aufzählen ist, brauchen Sie weder grep noch reguläre Ausdrücke oder ls!

echo complex* 

werden die Namen aller passenden Dateien zeigen, oder wenn Sie einen wollen pro Zeile,

printf '%s\n' complex* 

(Dies ist auch robuster, so im Allgemeinen einen besseren Ansatz. Vermeiden Sie sowohl ls und echo in Skripten, wenn Sie können.)

Um über übereinstimmende Dateien zu wiederholen, können Sie ls nicht zuverlässig verwenden.

for f in complex*; do 
    printf '%s\n' "$f" 
done 

Als Sonderfall, grep '*' sucht nach einem wörtlichen Sternchen. Einige Regex-Tools (zu Recht) scheitern mit einer Fehlermeldung für ungültige Regex (einschließlich * BSD grep; der Sonderfall ist in GNU grep).

+0

lernte eine Menge Dinge, von jetzt an werde ich nicht ls und echo in meinen Bash-Skripten verwenden, Vielen Dank für Hilfe – hungryWolf