Dateien mit grep auflisten?

7

Ich habe ein Verzeichnis, das die folgenden Dateien enthält:

file1a file1ab file12A2 file1Ab file1ab

Ich möchte alle Dateien auflisten, die mit file1höchstens zwei Buchstaben beginnen und von diesen gefolgt werden!

Die von mir vorgeschlagene Lösung lautet wie folgt:

ls | grep -i file1 [az] {2}

Aber es funktioniert nicht!

Ich möchte wissen warum? und wie auflisten?

Mahmoud Assyass
quelle

Antworten:

11

Sie brauchen keine Rohrleitungen grepoder ls. Verwenden Sie einfach Shell Globbing.

In bash, extglobMuster verwenden (sollte in interaktiven Sitzungen standardmäßig aktiviert sein, wenn nicht shopt -s extglob, um es zuerst festzulegen):

file1@(|?|??)

?stimmt mit einem einzelnen Zeichen überein und @(||)wählt eines der durch getrennten Muster aus |.

Wenn Sie nur Zeichen zwischen a-zund abgleichen möchten A-Z, verwenden Sie die Zeichenklasse, [:alpha:]die alle alphabetischen Zeichen im aktuellen Gebietsschema angibt:

file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]])

Beispiel:

$ ls -1
file1
file112
file11a
file12A2
file1a
file1ab
file1Ab
file1as
file2
fileadb

$ ls -1 file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]]))
file1
file1a
file1ab
file1Ab
file1as

zsh unterstützt dies nativ:

file1(|[[:alpha:]]|[[:alpha:]][[:alpha:]])

Ich beantworte diesen Teil sehr ungern auf Anfrage von OP.

Jeder zukünftige Leser, nicht analysieren ls, Globbing verwenden.

Verwenden von lsund grep:

ls | grep -E '^file1[[:alpha:]]{,2}$'

Beispiel:

% ls | grep -E '^file1[[:alpha:]]{,2}$'
file1
file1a
file1ab
file1Ab
file1as
heemayl
quelle
Vielen Dank ! aber das problem ist, dass wir das alles noch nicht studiert haben! Ist es möglich, diese Aufgabe mit lsund grepund Rohrleitungen zu erledigen ?
Mahmoud Assyass
1
@ MahmoudAssyass Überprüfen Sie meine Änderungen, aber Sie sollten unbedingt (lesen muss) Shell Globbing verwenden ..
heemayl
Es tut mir sehr leid, Sie zu stören! Mir ist bewusst, dass dich dumme Fragen nerven! Vielen Dank für
Ihre Unterstützung
1
@ MahmoudAssyass Komm schon ... niemand stört irgendjemanden ... ich bin sehr glücklich, dir zu helfen ... nur eine Einschränkung, dass du Globbing für diese Art von Aufgaben verwenden ls | grep ..
solltest,
Vielen Dank für Ihre Hilfe und auch für Ihre schnelle Antwort. Es wird definitiv geschätzt.
Mahmoud Assyass
3

Was ist mit finden?

find . -maxdepth 1 -regextype posix-egrep -iregex '\./file1[a-z]{,2}.*'
AB
quelle
Ich weiß sehr gut, dass wir dieses Problem dank anderer Methoden lösen können, aber ist es möglich, dies nur mit grepund lsund Rohrleitungen zu tun !
Mahmoud Assyass
1
Ich verstehe nicht, warum Sie sich auf grepund konzentrieren ls, außer als Übung. Findist der bevorzugte Weg, um solch komplizierte Aufgaben zu erledigen, da sie in einem einzigen Befehl ausgeführt werden können und keinen Shell-Master erfordern. Darüber hinaus kann es in großen Verzeichnissen VIEL effizienter sein, da keine nicht übereinstimmenden Zeichenfolgen ausgegeben werden müssen. Ein kleiner Wirkungsgrad zwar, aber dennoch ein Wirkungsgrad. Obwohl, ich muss zugeben , dass die Linie oben nicht ganz aussehen einschüchternd: findfür einfache Bedienung nicht bekannt :-)
Mark Gerolimatos
3

findwith -regexflag ist für diese Art von Job besser geeignet, insbesondere da es eine allgemeine Regel ist, dass die Ausgabe von ls niemals analysiert werden sollte .

Sie haben jedoch angegeben, dass Sie nur in einem Verzeichnis nach Dateien suchen (nicht in Unterverzeichnisse absteigend) und dass Sie dies ausdrücklich möchten lsund möchten grep. Die Lösung ist

\ls | grep -E 'file1[a-z]{2,}' 

In Anbetracht dessen, dass Sie im aktuellen Verzeichnis suchen, aber das Parsen vermeiden ls, ist hier eine andere Lösung

 for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done                                        
./file1ab
./file1abc

In meinem aktuellen Verzeichnis habe ich zwei Dateien file1abund file1abc. In beiden Fällen ist das Ergebnis wie folgt:

xieerqi:$ for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done                                        
./file1ab
./file1abc

xieerqi:$ \ls | grep -E 'file1[a-z]{2,}'                                                                            
file1ab
file1abc
Sergiy Kolodyazhnyy
quelle