2009-09-19 23 views

Antwort

28

Eine bessere Lösung: Versuchen Sie nicht, ls Ausgang an erster Stelle zu analysieren.

Die offizielle Wiki des irc.freenode.org #bash Kanal hat eine Erklärung, warum dies eine schlechte Idee ist, und welche alternative Ansätze, die Sie stattdessen nehmen können: http://mywiki.wooledge.org/ParsingLs

Verwendung von zu finden, stat und ähnliche Werkzeuge bieten die Funktionalität, die Sie suchen, ohne die Fallstricke (nicht alle sind offensichtlich - einige treten nur auf, wenn Sie auf Plattformen mit verschiedenen ls-Implementierungen umsteigen).

Für Ihr spezielles Beispiel, ich nehme an, dass Sie nur Dateien (und keine Verzeichnisse) im aktuellen Verzeichnis zu finden sind versuchen; Ihre aktuelle Implementierung mit ls -l ist fehlerhaft, da sie Dateien ausschließt, die + t- oder setuid-Berechtigungen haben. Der richtige Weg, dies zu realisieren wäre folgend:

find . -maxdepth 1 -type f -printf '%f\n' 
+2

Betrachten Sie die Verwendung von \ 0 anstelle von \ n, wenn Sie die Ausgabe in einen anderen Befehl wie 'grep -z' oder' xargs -0' eingeben. Dies bewirkt, dass "-printf" wie "-print0" funktioniert. –

+0

Wie kann ich das verwenden, aber nach Erweiterung filtern, zum Beispiel .txt? – inukaze

+0

@inukaze, setze '-name' * .txt'' vor '-printf' –

1

Es ist wahrscheinlich ein besserer Ansatz, die irgendwie Felder Kombination beinhaltet, aber:

 
$ echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14... | awk '{for (i = 9 ; i <= NF ; i++) printf "%s ", $i}' 
9 10 11 12 13 14... 

printf "%s " $i verwendet, wird der i-ten Feld mit einem Raum, nachdem es, statt eine neue Zeile drucken. Die for-Schleife sagt nur, von Feld 9 zum letzten Feld zu gehen.

+0

dies wird fehlschlagen, wenn es ein doppeltes Leerzeichen gibt –

1
echo 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 | awk 'BEGIN {OFS=ORS=""} ; {for (i=9;i<NF;i++) print $i " "; print $NF "\n"}' 
1

Wenn Sie noch auf dem ls -l bestehen statt finden oder anderen Werkzeugen, hier ist meine Lösung. Es ist nicht schön und destruktive:

  1. 1 $ Zerstören .. $ 8, indem sie auf „“ über eine for-Schleife
  2. die eine Reihe von Räumen Blätter vorhergehenden $ 9, entfernen sie den sub() Befehl
  3. drucken Sie die restlichen

    ls -l | awk '{für (i = 1; i < 9; i ++) $ i = ""; sub (/^* /, ""); print} '

+0

Es ist mehr Vorsicht geboten, wenn du 'ls' konfiguriert hast, um dir symbolische Links anzuzeigen (mit einem' ->/pfad/zu/Datei) 'am Ende); Streifen Sie es mit 'sed' ab. –

1

Nur für die Fertigstellung.

# just an exercise in regex matching ... 
ls -l | sed -E -e 1d -e /^[^-]/d -e 's/^([^ ]+ +){8}//' 
+0

@mikk Können Sie Ihren Befehl erklären? Ich denke, dass '-e/^ [^ -]/d' symlinks abbricht und -e's/^ ([^] + +) {8} // '' druckt die 9. Spalte, die nicht startet mit einem Leerzeichen, aber was macht '-e 1d'? – Dannid

+0

@Dannid, sieht für mich so aus, als würde es die erste Zeile löschen. Zitat aus der POSIX-Spezifikation, um zu erklären, warum: Wenn eine der Optionen "-l", "-g", "-n", "-o" oder "-s" angegeben ist, muss jede Liste von Dateien innerhalb des Verzeichnisses eine Statuszeile vorausgehen, die die Anzahl der Dateisystem-Blöcke angibt, die von Dateien in dem Verzeichnis in 512-Byte-Einheiten belegt sind, auf die nächste ganzzahlige Anzahl von Einheiten aufgerundet, falls erforderlich. Im POSIX-Gebietsschema lautet das Format: '" Gesamt% u \ n ", ' –

1

Eine Lösung ist zu kodieren & dekodieren der Raum mit einem Wort oder Zeichen unter Verwendung von sed:

ls -l | grep ^- | sed s/\ /{space}/ | awk '{print $9}' | sed s/{space}/\/

Dies ersetzt alle Räume in einer Linie mit {space} Es kann auch mit sed erfolgen bevor es an awk übergeben wird. Nachdem die Zeile an awk übergeben wurde, ersetzen wir {space} wieder durch Leerzeichen.

find wie bereits von anderen erwähnt ist eine viel bessere Lösung. Aber wenn Sie wirklich awk verwenden müssen, können Sie dies versuchen.

1
ls -l | grep ^- | awk -v x=9 '{print $x}' 

Ich benutze dies für den Erhalt von Dateinamen eines Verzeichnisses ohne Zwischenfall.Ich habe die Find-Lösung, die gut und dandy ist, wenn Sie nicht sicher sind, die Dateitypen, wenn Sie wissen, was Sie auf der ls -l funktioniert funktioniert gut, es alphabetisch auch standardmäßig bestellt.

Verwandte Themen