Wie liste ich unter Linux einen Dateinamen pro Ausgabezeile auf?

229

Ich verwende den ls -aBefehl, um die Dateinamen in einem Verzeichnis abzurufen, aber die Ausgabe erfolgt in einer einzelnen Zeile.

So was:

.  ..  .bash_history  .ssh  updater_error_log.txt

Ich benötige eine integrierte Alternative, um Dateinamen in einer neuen Zeile wie folgt abzurufen:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt
fixxxer
quelle
3
Es soll eine Liste für den menschlichen Verzehr anzeigen. Wenn Sie ls für einen anderen Zweck verwenden (z. B. um eine Liste von Dateien in einem Skript zum Durchlaufen zu erhalten), verwenden Sie mit Sicherheit das falsche Tool.
Juliano
2
@ Juliano - Es soll tatsächlich von einem Python-Skript verwendet werden. Warum nennst du es ein falsches Werkzeug?
Fixxxer
1
@fixxer In dem Moment, in dem Sie lszu Python weiterleiten , lswird eine Datei pro Zeile ausgegeben, wie in meiner Antwort erläutert.
Peter G.
6
@fixxxer: Dann benutzt du es tatsächlich falsch. Es formatiert die Liste für die Ausgabe im Benutzerterminal. Es kann Sonderzeichen im Dateinamen ersetzen, Zeichen mit besonderer Bedeutung usw. weglassen. Mit anderen Worten, ls formatiert dem Benutzer eine Liste. Sie möchten unformatierte Dateinamen. Gibt es einen besonderen Grund, warum Sie das Python-Modul 'glob' nicht verwenden? docs.python.org/library/glob.html Es gibt auch 'fnmatch', 'dircache' und andere.
Juliano
@fixxer Haben Sie tatsächlich für lsdie Ausgabe an pythonund den Single-Line - Ausgang in Python beobachtet?
Peter G.

Antworten:

430

Verwenden Sie die -1Option (beachten Sie, dass dies eine "Ein" -Ziffer ist, kein Kleinbuchstabe "L") wie folgt:

ls -1a

Stellen Sie jedoch zunächst sicher, dass Ihre lsUnterstützung -1. GNU Coreutils (auf Standard-Linux-Systemen installiert) und Solaris tun dies; aber im Zweifelsfall verwenden man lsoder ls --helpoder die Dokumentation überprüfen. Z.B:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b
Bert F.
quelle
2
+1 Ich wusste nichts über -1 (-l ja (ell nicht eins)) Es wird auf der Manpage
angezeigt,
@slashmais - Ah, guter Punkt - leicht zu verwechseln. Ich habe in der Antwort klargestellt.
Bert F
1
@dty: für GNU erhalten Sie dies in der ls --helpAusgabe dokumentiert ... immer installiert ;-)
Tony Delroy
3
Bei Google gesucht linux ls one file per lineund dies war der Top-Artikel. Ich kann nicht glauben, wie wortreich die gewählte Antwort ist oder dass diese Antwort weniger Stimmen hat als die, die an cat weitergeleitet wird. ls -1ftw.
Crantok
3
lsStandardmäßig wird das -1Verhalten verwendet, wenn der Ausgang nicht mit dem Terminal verbunden ist.
Codeforester
131

Ja, Sie können problemlos lseinen Dateinamen pro Zeile ausgeben:

ls -a | cat

Erläuterung: Der Befehl lserkennt, ob die Ausgabe an ein Terminal oder an eine Datei oder Pipe erfolgt, und passt sie entsprechend an.

Wenn Sie also ls -aauf Python weiterleiten, sollte dies ohne besondere Maßnahmen funktionieren.

Peter G.
quelle
2
Wow, das ist großartig. Der Vorteil gegenüber der akzeptierten Antwort - diese funktioniert tatsächlich auf Android / ADB-Shell - wo lses nur eine abgespeckte Version gibt, die nicht unterstützt wird-1
mkilmanas
Wie würden Sie jedoch vermeiden, dass die .und .."Dateien" in der Ausgabe angezeigt werden?
Matanster
@matanster: Kommt drauf an, möchtest du überhaupt Punktedateien sehen? Wenn nicht, lassen Sie einfach die Option -a fallen.
Peter G.
29

Ls ist für den menschlichen Verzehr konzipiert, und Sie sollten seine Ausgabe nicht analysieren .

In Shell-Skripten gibt es einige Fälle, in denen das Parsen der Ausgabe von ls der einfachste Weg ist, um den gewünschten Effekt zu erzielen. Da ls möglicherweise Nicht-ASCII- und Steuerzeichen in Dateinamen entstellt, sind diese Fälle eine Teilmenge derjenigen, bei denen kein Dateiname abgerufen werden muss ls.

In Python gibt es absolut keinen Grund, sich aufzurufen ls. In Python sind alle lsFunktionen integriert. Verwenden Sie os.listdirdiese Option, um den Inhalt eines Verzeichnisses aufzulisten und os.statoder osum Dateimetadaten abzurufen. Andere Funktionen in den osModulen sind wahrscheinlich auch für Ihr Problem relevant.


Wenn Sie über ssh auf Remote-Dateien zugreifen, können Sie Dateinamen mit sftp einigermaßen robust auflisten:

echo ls -1 | sftp remote-site:dir

Dadurch wird ein Dateiname pro Zeile gedruckt, und im Gegensatz zum lsDienstprogramm werden sftpnicht druckbare Zeichen nicht entstellt. Sie können Verzeichnisse, in denen ein Dateiname eine neue Zeile enthält, immer noch nicht zuverlässig auflisten, dies wird jedoch nur selten durchgeführt (denken Sie daran, dass dies ein potenzielles Sicherheitsproblem und kein Usability-Problem ist).

In Python (Vorsicht, Shell-Metazeichen müssen in Escapezeichen enthalten sein remote_dir):

command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir
remote_files = os.popen(command_line).read().split("\n")

Weitere Informationen zu komplexeren Interaktionen finden Sie im Batch-Modus von sftp in der Dokumentation.

Auf einigen Systemen (Linux, Mac OS X, möglicherweise einige andere Unices, aber definitiv nicht Windows) besteht ein anderer Ansatz darin, ein entferntes Dateisystem über ssh mit sshfs bereitzustellen und dann lokal zu arbeiten.

Gilles 'SO - hör auf böse zu sein'
quelle
Ich bin über SSH mit dem Remote-Computer verbunden. Ich habe keine Möglichkeit gefunden, eine Python-Funktion wie os.listdir auf dem Remote-Computer in einer einzigen Zeile auszuführen. Daher diese Frage. Ich möchte kein Skript schreiben, um einfach Dateien aufzulisten. Gibt es einen anderen Weg, um dieses Problem zu umgehen?
Fixxxer
@fixxxer: ssh ändert die Situation, es ist die Art von Dingen, die Sie in Ihrer ursprünglichen Frage hätten erwähnen sollen! Ich denke, SFTP ist für Ihren Anwendungsfall geeignet.
Gilles 'SO - hör auf böse zu sein'
Die Verwirrung tut mir leid. Gibt es eine Möglichkeit, das Passwort auch in die "Befehlszeile" einzufügen?
Fixxxer
@fixxxer: Ich weiß nicht, die Autoren von ssh missbilligen Passwörter, die im Klartext gespeichert sind, und neigen dazu, dies nicht einfach zu machen. Sie sollten wirklich eine schlüsselbasierte Authentifizierung einrichten (es gibt viele Tutorials im Web und Fragen dazu auf superuser.com ).
Gilles 'SO - hör auf böse zu sein'
11

Sie können verwenden ls -1

ls -l wird auch die Arbeit machen

ILF
quelle
In der Top-Antwort werden bereits die genauen Aussagen erwähnt. auch die Frage sagt ausdrücklich, ls -lsollte nicht verwendet werden.
DevX
2

Einfach, solange Ihre Dateinamen keine Zeilenumbrüche enthalten:

find . -maxdepth 1

Wenn Sie dies in einen anderen Befehl weiterleiten, sollten Sie Ihre Dateinamen wahrscheinlich lieber durch Null-Bytes als durch Zeilenumbrüche trennen, da Null-Bytes in einem Dateinamen nicht vorkommen können (aber Zeilenumbrüche können):

find . -maxdepth 1 -print0

Das Drucken auf einem Terminal wird wahrscheinlich als eine Zeile angezeigt, da normalerweise keine Null-Bytes gedruckt werden. Einige Programme benötigen möglicherweise eine bestimmte Option, um durch Nullen getrennte Eingaben zu verarbeiten, z. B. sort's -z. Ihr eigenes Skript müsste dies ebenfalls berücksichtigen.

8bittree
quelle