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 watch
dipanggil.
Anda watch head -n 17 *
adalah kerentanan perintah injeksi sewenang-wenang sebagai perluasan yang *
benar-benar ditafsirkan sebagai kode shell oleh shell yang watch
memanggil untuk menafsirkan gabungan dari argumen dengan spasi.
Jika ada file yang dipanggil $(reboot)
di direktori saat ini, itu akan reboot.
Dengan -x
, kami meminta watch
untuk 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 watch
menjalankan shell yang akan memperluas ./*
glob di setiap iterasi. watch foo bar
berlaku 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 zsh
itu 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 . -exec
atau sth seperti ini: D