Mit GNU awk
:
watch -x gawk '
FNR == 17 {nextfile}
ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}' ./*
Welches gibt eine Ausgabe wie:
./file1[17] line17
./short-file2[05] line 5 is the last
Beachten Sie, dass der ./*
Glob zum Zeitpunkt des Aufrufs nur einmal erweitert watch
wird.
Es handelte sich watch head -n 17 *
um eine Sicherheitsanfälligkeit bezüglich willkürlicher Befehlsinjektion, da deren Erweiterung *
von der Shell, watch
die die Interpretation der Verkettung ihrer Argumente mit Leerzeichen aufruft, tatsächlich als Shell-Code interpretiert wurde.
Wenn $(reboot)
im aktuellen Verzeichnis eine Datei aufgerufen würde, würde sie neu gestartet.
Mit -x
sagen wir, dass wir watch
die Shell überspringen und den Befehl direkt ausführen sollen. Alternativ können Sie Folgendes tun:
watch 'exec gawk '\''
FNR == 17 {nextfile}
ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'\'' ./*'
Zum watch
Ausführen einer Shell, die diesen ./*
Glob bei jeder Iteration erweitert. watch foo bar
ist in der Tat das gleiche wie watch -x sh -c 'foo bar'
. Bei der Verwendung watch -x
können Sie angeben, welche Shell Sie möchten, und beispielsweise eine leistungsstärkere Shell auswählen zsh
, die rekursives Globbing ausführen und sich auf reguläre Dateien beschränken kann:
watch -x zsh -c 'awk '\''...'\'' ./**/*(.)'
Ohne gawk
könnten Sie noch etwas tun wie:
watch '
for file in ./*; do
[ -s "$file" ] || continue
printf "%s: " "$file"
head -n 17 < "$file" | tail -n 1
done'
Geben Sie eine Ausgabe wie:
./file1: line17
./short-file2: line 5 is the last
Dies wäre jedoch viel weniger effizient, da mehrere Befehle pro Datei ausgeführt werden müssen.
find . -exec
oder so gemacht würde : D