Listet nur reguläre Dateien (aber keine Verzeichnisse) im aktuellen Verzeichnis auf


126

Ich kann verwenden, ls -ld */um alle Verzeichniseinträge im aktuellen Verzeichnis aufzulisten. Gibt es eine ähnlich einfache Möglichkeit, alle regulären Dateien im aktuellen Verzeichnis aufzulisten? Ich weiß, dass ich find verwenden kann

find . -maxdepth 1 -type f

oder stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

aber diese scheinen mir nicht übermäßig elegant zu sein. Gibt es eine nette kurze Möglichkeit, nur die regulären Dateien aufzulisten (mir sind Geräte, Pipes usw. egal), aber nicht die Unterverzeichnisse des aktuellen Verzeichnisses? Auch symbolische Links aufzulisten wäre ein Plus, ist aber keine Notwendigkeit.


5
Was meinst du mit "übermäßig elegant"? Soweit ich weiß, ist der findBefehl der beste Weg, um das zu tun, was Sie wollen. Für einige zuverlässige andere Optionen sollten Sie sich die Shell-spezifischen Befehle ansehen (und diese sind alles andere als portabel)!
Rahmu

@rahmu Ich war für etwas Ähnliches ls -d */, das kurz, einfach zu tippen und leicht zu verstehen ist. Daher bin ich mit Ulrich Dangel's Antwort ziemlich zufrieden, obwohl ich kein zsh verwende.
Daniel Kullmann

Antworten:


32

Mit zshund Glob Qualifiers können Sie es einfach direkt ausdrücken, zB:

echo *(.)

Je nach Konfiguration wird entweder nur die Liste der regulären Dateien oder ein Fehler zurückgegeben.

Für die Nicht-Verzeichnisse:

echo *(^/)

(Enthält symbolische Links (einschließlich zu Verzeichnissen), Named Pipes, Geräten, Sockets, Türen ...)

echo *(-.)

für reguläre Dateien und Symlinks zu regulären Dateien.

echo *(-^/)

für Nicht-Verzeichnisse und auch keine Symlinks zu Verzeichnissen.

Sehen Sie sich auch das DGlobbing-Qualifikationsmerkmal an, wenn Sie beispielsweise D ot-Dateien (versteckte Dateien) einschließen möchten *(D-.).


170
ls -p | grep -v / 

Dieser Befehl listet alle nicht ausgeblendeten Dateien auf, die keine Verzeichnisse sind (normale Dateien, Links, Gerätedateien usw.). Um auch versteckte Dateien einzuschließen, fügen Sie die -AOption zu hinzuls

Es wird davon ausgegangen, dass keine der Dateien Zeilenumbrüche im Namen enthält. Das Hinzufügen einer -qOption zum lsTransformieren aller nicht druckbaren Zeichen, einschließlich Zeilenvorschub in ?, stellt sicher , dass sie sich in einer Zeile befinden, und eignet sich daher zum Weiterleiten an ein zeilenbasiertes Dienstprogramm wie grepund zum Drucken auf einem Terminal.


14
+1, das ist eine gute Antwort. Das Abwählen eines neuen Benutzers ohne Kommentar ist für mich ziemlich schockierend, besonders wenn eine funktionierende Antwort vorliegt. Der einzige Randfall, bei dem ich feststellen kann, dass dies nicht richtig funktioniert, ist, dass ein Dateiname eine neue Zeile enthält. Auch das Beibehalten von Farben wäre eine schöne Ergänzung, wenn dies unterstützt wird. Für GNU könnte man hinzufügen , --color=alwaysum die ls, für OSX -G.
Graeme

Hallo, der Befehl, den Sie gegeben haben, ist großartig und hilft mir auf jeden Fall weiter. Ich habe mich jedoch gefragt, ob es möglich ist, den obigen Befehl zu verwenden und gleichzeitig die Dateiberechtigung zu ändern. Ich habe versucht, sudo chmod 777am Ende hinzuzufügen , und ich bekam Fehler ... Jede Hilfe wird sehr geschätzt
Dissidia

3
Wenn Sie auch Symlinks ausschließen möchten, die auf Verzeichnisse verweisen, tun Sie dies ls -pL | grep -v /. Die hinzugefügten -Ldereferences symbolische Links.
Matthias Braun

1
Wenn Sie auch Wildcard-Filter verwenden möchten, tun Sie dies ls -pdL something* | grep -v /. Die hinzugefügte -dOption listet die Verzeichnisse selbst und nicht deren Inhalt auf, sodass sie korrekt ausgeschlossen werden.
Rockallite

Und wenn Sie alle Dateien ohne Ordner
abrufen möchten,

23

So listen Sie nur reguläre Dateien auf:

ls -al | grep '^-'

Mit symbolischen Links (zu jedem Dateityp):

ls -al | grep '^[-l]'

Wo das erste Zeichen der Liste den Dateityp beschreibt, -bedeutet dies, dass es sich um eine reguläre Datei handelt, für die eine symbolische Verknüpfung besteht l.

Debian / Ubuntu

Geben Sie die Namen aller übereinstimmenden Dateien (einschließlich Links) aus:

run-parts --list --regex . .

Mit absoluten Pfaden:

run-parts --list --regex . "$PWD"

Drucken Sie die Namen aller Dateien /etc, die mit beginnen pund mit enden d:

run-parts --list --regex '^p.*d$' /etc

15

lsEs gibt keine Möglichkeit, dies zu tun, aber eines der schönen Dinge an Unix & Linux ist, dass langatmige und unelegante Pipelines leicht in ein Shell-Skript, eine Funktion oder einen Alias ​​umgewandelt werden können. und diese können wiederum wie jedes andere Programm in Pipelines verwendet werden.

(HINWEIS: Es gibt einige Probleme mit dem Gültigkeitsbereich von Funktionen und Aliasen. Für alle ausführbaren Dateien, die diese lesen und ausführen können, stehen Skripts zur Verfügung. Aliase und Funktionen sind nur in der aktuellen Shell verfügbar, auch wenn das .profile / .bashrc usw. einer Sub-Shell möglicherweise neu definiert wird Außerdem kann ein Skript in einer beliebigen Sprache geschrieben werden - einschließlich bash / sh, awk, perl, python und anderen - je nachdem, welche Sprache für den Job am besten geeignet ist oder mit welcher Sie am vertrautesten sind.

z.B

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

Ich habe xargs hinzugefügt, damit Sie alle üblichen lsOptionen verwenden können, zlsf -lrS

Da es verwendet wird find, werden alle normalerweise ausgeblendeten Punktedateien angezeigt und allen Dateinamen wird das Präfix ./ vorangestellt - das ist der einzige Unterschied, den Sie bemerken werden.

Sie könnten Punktedateien mit ausschließen, ! -iname '.*'aber dann müssten Sie zwei Versionen des Alias ​​haben - eine, die Punktedateien anzeigt, und eine, die keine hat.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Wenn lsfes sich um ein Skript und nicht um einen Alias ​​handelt, können Sie die Optionen auch analysieren (z. B. mit getopts oder / usr / bin / getopt oder ähnlichem) und Punktdateien ausschließen, sofern diese nicht -avorhanden sind.


-namereicht, brauchst du nicht -iname.
Totor

8
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

Die Option -F für ls hängt * an ausführbare Dateien, / an Verzeichnisse, @ an symbolische Links, = an Sockets und | zu FIFOs. Sie können dann grep verwenden, um die nicht regulären Dateizeichen von der Ausgabe auszuschließen, und Sie haben die Dateien. Dies funktioniert in jeder Shell, nicht nur in zsh.

Die Schwächen sind:

  1. Jede Datei , deren Name endet @, =oder |wird ausgeschlossen (aber Sie sollten nicht wirklich haben Dateien mit diesen Zeichen im Namen sowieso)
  2. Das schließt Gerätedateien oder einige exotische Dateitypen auf manchen Systemen wie Türen nicht aus.
  3. An jede ausführbare Datei wird ein Stern angehängt. Dies könnte durch Weiterleiten durch sed geschehen, um alle '*' - Zeichen aus der Ausgabe zu entfernen.
  4. Das funktioniert nicht richtig, wenn es Dateinamen gibt, die Zeilenumbrüche enthalten.

Auf dem System , schreibe ich dies auf 10% der Dateien haben Namen enthalten =, @oder |Zeichen. =ist in Maildir- oder Dateinamen üblich, die einen base64- oder quoted-printable-codierten Teil haben. @in Gebietsschemadefinitionen für E-Mail-Adressen und mehr. Es ist jedoch selten, dass sie am Ende des Dateinamens stehen. (Nur 31 von 2,2 Millionen auf diesem System zum Beispiel)
Stéphane Chazelas

3

Im Handbuch heißt es, dass die Option 'f' nur für 'reguläre Dateien' gilt, nicht für Pipes, Sockets oder Block / Char-Geräte. Das bedeutet, dass Sie bereits die richtigen Dinge tun.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)

0

Dies ist nicht besonders kurz, aber Sie können es in ein Skript oder einen Alias ​​umwandeln, wenn Sie es schnell aufrufen müssen. Verwenden Sie den Befehl ls als Eingabearray und rufen Sie ls -ld für jeden an grep weitergeleiteten Eintrag auf, um Verzeichnisse auszuschließen, deren Ausgabe an null gesendet wurde. Wenn dies erfolgreich war, geben Sie die ursprüngliche Eingabe ein:

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Sie können die Ausgabe von grep und conditional invertieren, die gleichen Ergebnisse:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

\dev\null?!?!
Manatwork


0

Dies ist ein etwas alter Thread, aber der sauberste Weg, nur Dateien aufzulisten.

ls -al | grep '^-' | awk '{print $9}'


1
touch "some file name"um ein kurzes Gegenbeispiel zu sehen
Jeff Schaller

@ JeffSchaller Sie haben einen gültigen Punkt. Dafür so etwas. ls -al | grep '^-' | awk '{ for(i=9; i<=NF; ++i) printf $i""FS; print "" }', sollten die Dateien mit Leerzeichen behandeln.
RJ
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.