Entfernen Sie die ersten 8 Spalten aus der Ausgabe von ls mit AWK

499
Jesus DA

Ich möchte AWK verwenden, um die ersten 8 Spalten aus der folgenden Ausgabe zu entfernen:

 ls -l  lrwxrwxrwx 1 user user 23 jul 27 00:04 file1.pdf -rw-rw-r-- 1 user user 107 may 8 13:59 file 2 with spaces.mp3 lrwxrwxrwx 1 user user 11 jul 24 19:43 file3-with-hyphens.txt lrwxrwxrwx 1 user user 11 jul 24 19:43 and_another_file4_with_underscores.md -rw-rw-r-- 1 user user 107 may 8 13:59 file 5 with way more spaces than the rest.mp3 

und senden Sie das Ergebnis in eine Textdatei. Ich kann das manuell in vim mit visueller Blockauswahl machen, aber ich würde es vorziehen, ein Skript zu haben, das automatisch ausgeführt wird.

Bei einem Blick auf die Seite konnte ich diese Seite finden, auf der ich durch Ändern der relevanten Teile des 9. Beispiels und die Ausgabe der Ausgabe so oft wie nötig zu sich selbst gelangte, um das gewünschte Ergebnis zu erzielen, aber ich glaube, dass es einen besseren geben muss (eleganter und / oder kompakter), aber nicht in der Lage, es zu finden oder sich meine eigenen zu überlegen.

Mein endgültiger Code lautet wie folgt:

awk '' x=1 ~/file_folder_content.txt | awk '' x=1 | ... | awk '' x=1 >> ~/file_folder_content.txt 

Hinweis 1: Ich gehe davon aus, dass die tatsächliche Ausgabe des lsBefehls viel größer ist.

Hinweis 2: Ich habe versucht, das neunte Feld zu drucken. Da jedoch einige Dateinamen Leerzeichen enthalten, wird nur das erste Wort im Dateinamen gedruckt.

1
Die ersten 8 Spalten entfernen? Diese Ausgabe hat nur 8 Spalten. Versuchen Sie, nur die Dateinamen auszudrucken? ls -1 macht das. confetti vor 5 Jahren 1
Versuch und Irrtum ließen mich mit diesem lächerlichen Befehl zurück: `ls -l | Schwanz -n +2 | Spalte -tdN Test -o "|" | cut -d "|" -f 9` - Es wird nur die 9. Spalte gedruckt. Es muss einen besseren Weg geben, aber hey, es funktioniert, lol. confetti vor 5 Jahren 0

2 Antworten auf die Frage

1
simlev

Dies sollte das tun, was Sie wollen awk:

ls -l | awk '$9~/./; gsub(/^ +/,""); print}' 

Hier ist ein etwas anderer Ansatz in perl:

ls -l | perl -lane 'if ($F[7]=~/./) ' 

Hinweis: Ich kann Ihnen nur empfehlen, gründlich darüber nachzudenken, was Sie tatsächlich erreichen möchten, da es möglicherweise bessere Möglichkeiten gibt. Wie von @confetti erwähnt, ist das Drucken der Dateinamen einfacher mit ls -1.

Anmerkung: Wie in den Kommentaren richtig hervorgehoben, ist diese Lösung nicht robust. Ich würde hinzufügen, dass das Parsen von lsnicht als sicher betrachtet werden kann.

AWK lernen: Da das OP in den Kommentaren erklärt hat, dass diese Frage Teil eines umfassenderen Bestrebens ist, AWK zu beherrschen, habe ich einige Empfehlungen.

  • Gehen Sie dieses schöne AWK- Tutorial durch
  • Halten Sie dieses Referenzhandbuch immer geöffnet
  • Lesen Sie diesen kurzen Artikel über die integrierten Variablen von AWK
  • Lesen Sie einige der unzähligen Antworten auf AWK- Fragen zu StackExchange
  • Betrachten Sie die Alternativen, zusammengefasst hier
Erstellen Sie eine Datei mit mehreren aufeinanderfolgenden Leerzeichen im Namen und sehen Sie, was Ihr Befehl dafür druckt. Kamil Maciorowski vor 5 Jahren 1
(für das awk) oder eine Datei mit dem Namen "0000" oder "-00.00" oder "0e42" dave_thompson_085 vor 5 Jahren 1
@ dave_thompson_085 rechtmäßige Beobachtung! Dieser bedeutsame Fall kann berücksichtigt werden, indem "$ 9" durch "$ 9 ~ /./" und "$ F [7]" durch "$ F [7] = ~ /./" ersetzt wird `Ausgabe sollte überprüft werden. simlev vor 5 Jahren 0
@simlev Das breitere Problem, das ich zu lösen versuche, besteht darin, mit AWK vertraut zu werden. Dies war nur ein Problem, das ich zum Üben hatte, aber keinen Lösungsweg finden konnte (abgesehen von dem von mir bereitgestellten Code ). Ich hatte erwartet, dass dies ein ziemlich ineffizienter Weg ist, aber ich habe auch erwartet, einen besseren Weg zu lernen. Jesus DA vor 5 Jahren 0
@simlev Ich habe die Ausgabe Ihrer Antwort mit meiner manuell bearbeiteten Datei "unterschiedlich" und sie sind gleichwertig. Dies ist also die Antwort, nach der ich gesucht habe. Außerdem gibt es eine bessere Möglichkeit, dies zu tun, und weist auf die Mängel hin, die beim Analysieren des Ergebnisses von 'ls' bestehen. Jesus DA vor 5 Jahren 0
0
Kamil Maciorowski

Das sieht nach einem XY-Problem aus . ls -1sollte drucken, was Sie wollen. Diese Option wird von POSIX benötigt, so dass Sie sie wahrscheinlich lsnicht unterstützen.

Wenn Sie jedoch das Ergebnis analysieren, solltenls Sie es überhaupt nicht verwenden . Verwenden Sie findvorzugsweise mit -print0Aktion.

Ist lsalso nicht das richtige Werkzeug. Wenn Sie lstrotzdem darauf bestehen, die bloße Ausgabe zu analysieren, ist das awkmöglicherweise auch nicht das richtige Werkzeug. Argumentation:

  • Ihre Spalten sind durch Leerzeichen getrennt. Manchmal gibt es zwei oder drei aufeinander folgende Leerzeichen, dies unterscheidet sich von Zeile zu Zeile. Mit diesem naiven Trennzeichen kann ein Dateiname in einer Zeile mit der N-ten Spalte beginnen, während er in einer anderen Zeile in der (N + 1) -ten Spalte liegt.
  • Sie können festlegen awk, dass mehrere Leerzeichen als ein Trennzeichen ( awk -F ' +') behandelt werden sollen. Dies führt jedoch dazu, dass Dateinamen mit vielen aufeinanderfolgenden Leerzeichen beschädigt werden.
  • Sie brauchen also eine Logik, um zu ermitteln, wo in jeder Zeile ein Dateiname beginnt. Dies ist möglich (ich glaube, dass awkTuring abgeschlossen ist), aber ich kann Ihnen keine funktionierende Lösung geben.

Sogar die Ausgabe von ls -1sollte nicht geparst werden, ls -list schlechter.

Wenn Sie darauf hingewiesen haben, dass "ls" nicht robust ist, ist es nicht mehr sinnvoll zu spekulieren, wie es mit einem bestimmten Tool analysiert werden könnte. Um weiter zu beweisen, wie völlig nutzlos das ist, habe ich zum einen Gruppennamen, die Leerzeichen enthalten. simlev vor 5 Jahren 0