Saya ingin mengganti satu set karakter dengan karakter yang sesuai dari set lain, sesuatu seperti ini:
original set: ots
"target" set: u.x
foobartest → fuubar.ex.
Terjemahan / transliterasi seperti ini adalah spesialisasi dari tr
perintah:
$ echo 'foobartest' | tr 'ots' 'u.x'
fuubar.ex.
Sayangnya tr
tidak mendukung mengubah file di tempat seperti sed
halnya.
Saya ingin menggunakan sed
jadi saya tidak perlu menemukan kembali roda juggling file temp.
tr
(dengan benar) mengabaikan rekursi dalam set pengganti:echo 'abc' | tr ab bx
→bxc
. Solusi primitif mungkin memotong ituxxc
karena menerapkan kembali terjemahan ke karakter yang telah diterjemahkan.sed
bertentangan dengan GNUtr
dapat transliterasi karakter multi-byte)Jawaban:
sed
memilikiy
perintah yang berfungsi sepertitr
:The
y
perintah bagian POSIXsed
spesifikasi , sehingga harus bekerja pada hampir platform apapun.Dan karena itu
sed
, Anda dapat memilikinya mengganti file dengan versi yang diedit, membuat Anda tidak perlu repot dengan bisnis file temp (asalkan implementasi Andased
mendukung-i
opsi, yang tidak ditentukan oleh POSIX):sumber
sed
itu tidak berarti fungsi lain juga. ;) Milis Vim memiliki utas tentang menemukan yangy/abc/def/
setara; pilihan terbaik tampaknya:%call setline(".", tr(getline("."),"abc","def"))
.Jika seperti dalam kasus Anda, Anda mentransiterasi karakter tanpa mengubah ukurannya (bagaimanapun, beberapa implementasi seperti GNU
tr
hanya mendukung karakter byte tunggal), Anda dapat melakukan:Artinya,
tr
timpa file itu sendiri.Itu lebih baik daripada
sed -i
di beberapa akun:Salah satu kelemahannya adalah jika itu terputus, file akan berakhir setengah diterjemahkan (dalam hal ini, Anda dapat menjalankannya lagi untuk menyelesaikannya). Beberapa
sed
implementasi akan menanganinya dengan benar dengan memastikan file asli tetap tidak berubah kecuali perintah berhasil.sumber
echo 'abc' | tr ab bx
.tr
dan dalam lingkungan PXE symlink-berat kami,sed -i
adalah menunggu menunggu. terjadi ...: /iconv -t cp437
tampaknya lebih tepat untuk itu.iconv
rusak ketika file input sudah mengandung byte yang di-encode cp437, atau campuran dari beberapa encoding. Jadi sementara itu lebih disukai dalam kasus umum, itu lebih kuat untuk melakukan penggantian manual pada kasus ini.Sebagai alternatif lain, jika masalah utama Anda adalah kurangnya dukungan untuk mengubah file di tempat, Anda mungkin tertarik pada
sponge
alat dari paket moreutils :akan menulis
file
, tetapi hanya terbukafile
untuk menulis setelah input selesai. Dari halaman manual :Kecuali jika Anda memiliki file yang sangat besar yang tidak dapat disimpan dalam memori, ini
sponge
dapat bekerja untuk Anda.sumber
sponge
itu masih menimpafile
jikatr
gagal (misalnya jika Anda telah menulis tetapi tidak membaca akses kefile
)cat file >; file
operator ksh93 yang menulis output ke tempfile yang diubah namanya menjadi tujuan hanya jika perintah berhasil (tetapi sepertised -i
, yang membuat file baru alih-alih menimpa yang asli).