Saya memiliki file dalam pengkodean UTF-8 dengan BOM dan ingin menghapus BOM. Apakah ada alat baris perintah linux untuk menghapus BOM dari file?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
Saya memiliki file dalam pengkodean UTF-8 dengan BOM dan ingin menghapus BOM. Apakah ada alat baris perintah linux untuk menghapus BOM dari file?
$ file test.xml
test.xml: XML 1.0 document, UTF-8 Unicode (with BOM) text, with very long lines
Jawaban:
Jika Anda tidak yakin apakah file tersebut mengandung BOM UTF-8, maka ini (dengan asumsi implementasi GNU sed
) akan menghapus BOM jika ada, atau tidak membuat perubahan jika tidak.
sed '1s/^\xEF\xBB\xBF//' < orig.txt > new.txt
Anda juga dapat menimpa file yang ada dengan -i
opsi:
sed -i '1s/^\xEF\xBB\xBF//' orig.txt
en_US.UTF-8
lokal dan berhasil. Kapan itu akan gagal?
1s/
berarti hanya mencari baris pertama; jalur lain tidak terpengaruh. The ^
berarti hanya cocok di awal (pertama) line. \xEF\xBB\xBF
adalah BOM UTF-8 (lolos string hex). //
berarti ganti dengan yang tidak ada. Saya bisa menambahkan 1
ke akhir (untuk 1s/^xEF\xBB\xBF//1
), yang berarti hanya cocok dengan kemunculan pertama dari pola di telepon. Tetapi karena pencarian itu berlabuh ^
, ini tidak akan membuat perbedaan. Jika file tidak memiliki BOM di awal baris pertama, polanya tidak akan cocok, dan dengan demikian tidak ada perubahan yang dibuat.
BOM tidak masuk akal dalam UTF-8. Itu umumnya ditambahkan secara tidak sengaja oleh perangkat lunak palsu pada OS Microsoft.
dos2unix
akan menghapusnya dan juga menangani keanehan lain dari file teks Windows.
dos2unix test.xml
dos2unix
?
Dimungkinkan untuk menghapus BOM dari file dengan tail
perintah:
tail -c +4 withBOM.txt > withoutBOM.txt
tail
menggunakan pengindeksan berbasis 1 ?! WTF!
tail -c -1
atau tail -c 1
(apa tail
yang biasanya digunakan) adalah konten yang dimulai dengan byte terakhir, tail -c +1
dimulai dengan byte pertama. tail -c 0
/ tail -c +0
untuk itu akan jauh lebih tidak intuitif.
(dd bs=1 count=3 of=/dev/null; cat) <input >output
. Atau dengan GNU (head -c3 >/dev/null; cat)
- bahkan di UTF8 atau lokal non-singlebyte lainnya; GNU head melakukan 'char' = byte.
Buka file dalam VIM:
vi text.xml
Hapus pengodean BOM:
:set nobomb
Simpan dan keluar:
:wq
<feff>
, namun :set nobomb
tidak mengubah atau menghapusnya.
Anda dapat gunakan
LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename
untuk menghapus tanda urutan byte dari awal file, jika ada, serta mengubah baris baru CR LF menjadi LF saja. The LANG=C LC_ALL=C
memberitahu shell Anda ingin perintah untuk menjalankan dalam default C lokal (juga dikenal sebagai default POSIX lokal), di mana tiga byte membentuk Byte Order Mark diperlakukan sebagai byte. The -i
pilihan untuk sed berarti di tempat. Jika Anda menggunakan -i.old
, maka sed menyimpan file asli sebagai filename.old
, dan file baru (dengan modifikasi, jika ada) sebagai filename
.
Saya pribadi suka memiliki ini sebagai ~/bin/fix-ms
; misalnya, sebagai
#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
for FILE in "$@" ; do
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
done
else
exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi
jadi jika saya perlu menerapkan ini untuk mengatakan semua file sumber C dan header (kode lama saya dari era MS-DOS, misalnya!), saya hanya menjalankan
find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix
atau, jika saya hanya ingin melihat file seperti itu, tanpa memodifikasinya, saya dapat menjalankannya
~/bin/ms-fix < filename | less
dan tidak melihat jelek <U+FEFF>
di terminal UTF-8 saya.
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"
?
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$@"
tidak berhasil; itu mengembalikan kode keluar, tetapi memproses semua file yang terdaftar dalam daftar argumen sebelum keluar.
--
Sebelum nama file, tentu saja, penting: tanpa itu, nama file yang dimulai dengan tanda hubung dapat dianggap sebagai opsi oleh sed. Saya mengeditnya menjadi jawaban saya; terima kasih atas pengingatnya!
Baru-baru ini saya menemukan alat baris perintah kecil ini yang menambah atau menghapus BOM pada file UTF-8 yang disandikan arbiter : UTF BOM Utils ( tautan baru di github)
Sedikit kekurangan, Anda hanya dapat mengunduh kode sumber C ++ polos. Anda harus membuat makefile (dengan CMake , misalnya) dan mengompilasinya sendiri, biner tidak disediakan di halaman ini.