Saya memiliki skrip bash yang menghitung setiap file *.php dalam direktori dan menerapkan iconv
untuk itu. Ini mendapatkan output di STDOUT.
Sejak menambahkan -o
parameter ( dalam pengalaman saya ) sebenarnya menulis file kosong mungkin sebelum konversi terjadi, bagaimana saya bisa menyesuaikan skrip saya sehingga melakukan konversi, lalu menimpa file input?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
Jawaban yang Diterima:
Ini tidak berfungsi karena iconv
pertama membuat file output (karena file sudah ada, itu memotongnya), kemudian mulai membaca file inputnya (yang sekarang kosong). Sebagian besar program berperilaku seperti ini.
Buat file sementara baru untuk output, lalu pindahkan ke tempatnya.
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Jika iconv
platform Anda tidak memiliki -o
, Anda dapat menggunakan pengalihan shell untuk efek yang sama.
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
sponge
Colin Watson utilitas (termasuk dalam moreutils Joey Hess) mengotomatiskan ini:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Jawaban ini tidak hanya berlaku untuk iconv
tetapi untuk program filter apa pun. Beberapa kasus khusus perlu disebutkan:
- GNU sed dan Perl
-p
memiliki-i
opsi untuk mengganti file di tempatnya. - Jika file Anda sangat besar, filter Anda hanya mengubah atau menghapus beberapa bagian tetapi tidak pernah menambahkan sesuatu (mis.
grep
,tr
,sed 's/long input text/shorter text/'
), dan Anda suka hidup berbahaya, Anda mungkin ingin benar-benar memodifikasi file di tempatnya (solusi lain yang disebutkan di sini membuat file output baru dan memindahkannya ke tempatnya di akhir, sehingga data asli tidak berubah jika perintah disela untuk alasan apapun).