Iterieren über jede Zeile der ls-l-Ausgabe


119

Ich möchte über jede Zeile in der Ausgabe von: iterieren. ls -l /some/dir/*

Im Moment versuche ich: for x in $(ls -l $1); do echo $x; done

Dies iteriert jedoch über jedes Element in der Zeile separat, sodass ich Folgendes erhalte:

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:07
File1

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:17
File2

Ich möchte jedoch jede Zeile als Ganzes durchlaufen. Wie mache ich das?


1
Zitieren Sie immer Variablen (und die Befehlsausgabe), es sei denn, Sie haben einen bestimmten Grund, dies nicht zu tun.
Glenn Jackman

Antworten:


246

Stellen Sie IFS wie folgt auf newline ein:

IFS='
'
for x in `ls -l $1`; do echo $x; done

Legen Sie eine Sub-Shell darum, wenn Sie IFS nicht dauerhaft festlegen möchten:

(IFS='
'
for x in `ls -l $1`; do echo $x; done)

Oder verwenden Sie while | Lesen Sie stattdessen:

ls -l $1 | while read x; do echo $x; done

Eine weitere Option, mit der while / read auf derselben Shell-Ebene ausgeführt wird:

while read x; do echo $x; done << EOF
$(ls -l $1)
EOF

12
Vorsicht beim Piping zu while, das while wird in einer Subshell ausgeführt, was bedeutet, dass Variablen im Hauptprozess nicht geändert werden konnten
Reorx

1
Was macht der $ 1 hier? Ich muss dies in einem Skript verwenden, das ich schreibe und das Argumente akzeptiert. Der $ 1 wirft die Dinge ab. Was kann ich dort anstelle von 1 US-Dollar setzen, um den gleichen Effekt zu erzielen? Ich möchte die zweite Lösung verwenden.
Noob-in-Need

@ Noob-in-Need Ersetzen Sie es durch das Verzeichnis, das Sie
auflisten

1
Möglicherweise möchten Sie dies tun, read -roder Bash entfernt nicht entkoppelte Backslashes aus den Daten.
Brian Gordon

6

Es hängt davon ab, was Sie mit jeder Zeile tun möchten. awk ist ein nützliches Dienstprogramm für diese Art der Verarbeitung. Beispiel:

 ls -l | awk '{print $9, $5}'

.. druckt auf meinem System den Namen und die Größe jedes Elements im Verzeichnis.


3

Wie bereits erwähnt, ist awk das richtige Werkzeug dafür. Wenn Sie awk nicht verwenden möchten, anstatt die Ausgabe von "ls -l" Zeile für Zeile zu analysieren, können Sie alle Dateien durchlaufen und für jede einzelne Datei ein "ls -l" wie folgt ausführen:

for x in * ; do echo `ls -ld $x` ; done

3

Sie können den findBefehl auch ausprobieren . Wenn Sie nur Dateien im aktuellen Verzeichnis möchten:

find . -d 1 -prune -ls

Führen Sie einen Befehl für jeden von ihnen aus?

find . -d 1 -prune -exec echo {} \;

Zeilen zählen, aber nur in Dateien?

find . -d 1 -prune -type f -exec wc -l {} \;


Fund ist kaputt. Oft bekomme ich einige bizarre Fehlermeldungen. Es möchte mir helfen, wenn die Befehlszeile vollkommen gültig ist, und es scheint, als würde es nach dem nächsten Neustart möglicherweise nicht aufhören, sobald es damit beginnt. In Bezug auf Fehler scheint es manchmal zufällig zu sein. Ich bin mir nicht sicher, wie ich den Fehler melden kann.
Jim Michaels

1

Das Dienstprogramm read (1) und die Ausgabeumleitung des Befehls ls (1) machen das, was Sie wollen.


-1

Warum hat niemand vorgeschlagen, nur Optionen zu verwenden, die die Teile eliminieren, die er nicht verarbeiten möchte?

Auf dem modernen Debian erhalten Sie einfach Ihre Datei mit:

ls --format=single-column 

Außerdem müssen Sie nicht darauf achten, in welchem ​​Verzeichnis Sie es ausführen, wenn Sie das vollständige Verzeichnis verwenden:

ls --format=single-column /root/dir/starting/point/to/target/dir/

Diesen letzten Befehl verwende ich oben und erhalte die folgende Ausgabe:

bot@dev:~/downloaded/Daily# ls --format=single-column /home/bot/downloaded/Daily/*.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141119_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141120_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141121_IENT1.txt.gz
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.