Apakah mungkin untuk menggunakan gawk
's -i inplace
pilihan dan juga mencetak hal yang stdout
?
Misalnya, jika saya ingin memperbarui file, dan jika ada perubahan, cetak nama file dan baris yang diubah ke stderr
saya bisa melakukan sesuatu seperti
find -type f -name 'myfiles' -exec gawk -i inplace '{if(gsub(/pat/, "repl")) { print FILENAME > "/proc/self/fd/2" ; print > "/proc/self/fd/2"; } print;}' {} +
tetapi apakah ada cara untuk menggunakannya stdout
, atau cara yang lebih bersih untuk mencetak blok itu ke aliran alternatif?
find -type f -name 'myfiles' -exec grep -q 'pattern' {} \; -print -exec gawk -i inplace '{do_your_sub_and_print_to_dev/stderr_too}' {} \;
itu Anda hanya akan menggunakan awk untuk mengedit file yang benar-benar berisi garis yang cocok dengan pola itu.grep
bisa. Naluri pertama saya adalah untuk menghindari "proses" file dua kali, tetapi saya tidak akan terkejut sama sekali jika memang lebih cepat. Itu hanya untuk menunjukkan mengapa saya bisa memercayai nyali saya pada tugas pembuatan profil-print -exec gawk
tidak dieksekusi lagi) dan 2) itu akan berhenti pada pertandingan pertama jadi kecuali pertandingan pertama ada di baris terakhir Anda masih belum memproses seluruh file dua kali (ini lebih seperti 1,X kali). Juga, jikagawk -i inplace
berfungsi sepertised -i
itu akan mengedit file di tempat - yaitu memperbarui cap waktu, inode dll bahkan jika tidak ada yang perlu diedit ...Jawaban:
Anda harus menggunakan
/dev/stderr
atau/dev/fd/2
bukannya/proc/self/fd/2
.gawk
menangani/dev/fd/x
dan/dev/stderr
dengan sendirinya (terlepas dari apakah sistem memiliki file-file itu atau tidak).Ketika Anda melakukan:
gawk
tidakwrite(2, "x\n")
, sementara ketika Anda melakukannya:karena tidak memperlakukan
/proc/self/fd/x
secara khusus, ia melakukan:Pertama
/proc/self/fd
adalah Linux khusus dan di Linux mereka bermasalah. Dua versi di atas tidak setara ketika stderr adalah untuk file biasa atau yang dapat dicari lainnya atau ke soket (untuk yang terakhir akan gagal) (belum lagi bahwa itu membuang deskriptor file).Yang sedang berkata, jika Anda perlu menulis ke stdout asli, Anda perlu menyimpannya di fd lain seperti:
gawk
melakukan redirect stdout dengan di tempat ke file. Ini diperlukan karena misalnya, Anda ingin:untuk menyimpan
uname
output ke dalamfile
.sumber
Just for fun, pendekatan alternatif hanya menggunakan POSIX fitur dari
find
,sh
,grep
dan (terutama)ex
:(Semua jeda baris dalam perintah di atas adalah opsional; dapat disingkat menjadi satu-liner.)
Atau, bisa dibilang lebih terbaca:
:)
(Perintah ini belum diuji; suntingan diterima jika saya membuat kesalahan.)
sumber