Dengan GNU awk:
watch -x gawk '
FNR == 17 {nextfile}
ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}' ./*
Yang memberikan output seperti:
./file1[17] line17
./short-file2[05] line 5 is the last
Perhatikan bahwa ./*gumpalan diperluas hanya sekali pada saat watchdipanggil.
Anda watch head -n 17 *adalah kerentanan perintah injeksi sewenang-wenang sebagai perluasan yang *benar-benar ditafsirkan sebagai kode shell oleh shell yang watchmemanggil untuk menafsirkan gabungan dari argumen dengan spasi.
Jika ada file yang dipanggil $(reboot)di direktori saat ini, itu akan reboot.
Dengan -x, kami meminta watchuntuk melewati shell dan menjalankan perintah secara langsung. Atau, Anda bisa melakukan:
watch 'exec gawk '\''
FNR == 17 {nextfile}
ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'\'' ./*'
Untuk watchmenjalankan shell yang akan memperluas ./*glob di setiap iterasi. watch foo barberlaku sama dengan watch -x sh -c 'foo bar'. Saat menggunakan watch -x, Anda dapat menentukan shell mana yang Anda inginkan dan misalnya memilih yang lebih kuat seperti zshitu dapat melakukan globbing rekursif dan membatasi ke file biasa:
watch -x zsh -c 'awk '\''...'\'' ./**/*(.)'
Tanpa gawk, Anda masih bisa melakukan sesuatu seperti:
watch '
for file in ./*; do
[ -s "$file" ] || continue
printf "%s: " "$file"
head -n 17 < "$file" | tail -n 1
done'
Memberikan ouput seperti:
./file1: line17
./short-file2: line 5 is the last
Tapi itu akan menjadi jauh lebih efisien karena ini berarti menjalankan beberapa perintah per file.
find . -execatau sth seperti ini: D