2017-02-14 1 views
-1

Ich versuche, die ersten 10 Zeilen aller Dateien in einem Verzeichnis zu drucken. Derzeit verwende ich:Kopf funktioniert nicht, wenn ein Ergebnis von ls | grep

ls -p | grep -v/

alle Verzeichnisse aus dem Ergebnis von ls zu entfernen, und kehren Sie einfach die Dateien im Verzeichnis. Als ich dann tun:

ls -p | grep -v/| head 

ich, dass die ersten zehn Zeilen von allen Dateien gedruckt werden würden erwarten würde, aber es funktioniert nicht.

Würde jemand helfen können?

+0

Wenn ein Befehl nicht das tut, was Sie * erwarten *, dann lesen Sie die Manpage! – hek2mgl

+0

@ hek2mgl offensichtlich, das war das erste, was ich tat – FlapJack

+0

Wie können Sie dann erwarten, dass "Kopf" liest eine Liste von Dateinamen von Stdin und druckt die ersten 10 Zeilen davon? – hek2mgl

Antwort

2

Ihr Fehler geht davon aus, dass Argumente, die ein Befehl von der Standardeingabe erhält. Es ist nicht.

Wenn head Daten von einem Piped-Befehl empfängt, erhält er einen Datenstrom. Der Befehl head liest diese Daten genau so, als würde er aus einer Datei lesen, die als Argument übergeben wurde. Denken Sie daran, auf diese Weise (dies ist Pseudo-Code, es wird nicht funktionieren):

PSEUDO_PIPELINE <= ls -p | grep -v/# Not valid shell syntax 
head PSEUDO_PIPELINE     # Not valid shell syntax 

Es ist eigentlich ein (gültig) Art und Weise zum Ausdruck bringen, genau das, und es ist Prozess Substitution genannt:

head <(ls -p | grep -v /) 

Dadurch wird das exakt gleiche (unerwünschte) Ergebnis erreicht, das Sie beobachtet haben, es wird jedoch deutlicher, dass der Befehl vor der Pipe wirklich eine Datei und keine Argumentliste ist.

Die Standardeingabe (sowie Standardausgabe und Standardfehler der Ausgabestreams) wird von jedem Befehl aus seinem Startkontext empfangen. Es ist wie ein "verstecktes Argument", wenn Sie möchten, und der Prozess kann damit interagieren (indem Sie von ihm lesen, bis es das Ende der Datei erreicht, weil es eine spezielle Datei ist, aber trotzdem eine Datei).

Nun sollten Sie verstehen, warum Sie die ersten 10 10 Zeilen der vorhergehenden Befehle erhalten, und NICHT die ersten 10 Zeilen jeder Datei.

könnten Sie erreichen, was Sie mit etwas wollen, dass diese wie:

find . -mindepth 1 -maxdepth 1 -type f -exec printf "\n%s ------\n" {} \; -exec head {} \; 

Dies findet jede Datei, und druckt dann eine Kopf-/Trennlinie, und die ersten Zeilen jeder Datei.

+0

Danke für die Antwort, das ist eine großartige Erklärung. Sollte das Beispiel, das Sie unten angegeben haben, so funktionieren wie es ist? Oder muss ich etwas ändern, um es spezifisch zu machen? – FlapJack

+0

@FlapJack Es sollte funktionieren wie es ist (es wird Dateien aus dem aktuellen Verzeichnis verwenden). Wenn Sie die Kopfzeile/Trennlinie entfernen und den Dateiinhalt nur fortlaufend drucken lassen möchten, können Sie den Befehl vereinfachen, indem Sie den Teil vom ersten -exec zum ersten '\;' entfernen. – Fred

+0

Ja, ich habe es versucht, aber ich habe den Platz nach dem Drucken nicht bemerkt, also ist es fehlgeschlagen. Danke für Ihre Hilfe – FlapJack

2

alle Dateien zu finden, die keine Verzeichnisse im aktuellen Verzeichnis sind:

find . -mindepth 1 -maxdepth 1 -type f 

Dann können Sie -exec verwenden, um einen Befehl auf jedem dieser Dateien auszuführen.

+0

Das ist toll, vielen Dank – FlapJack

Verwandte Themen