Bagaimana menghapus simbol ini "^ @" dengan vim?

59

Saya memiliki beberapa file yang rusak dengan simbol ini:

^ @

Itu bukan bagian dari string; itu tidak dapat ditelusuri. Bagaimana cara mengganti simbol ini dengan tidak ada, atau bagaimana cara menghapus simbol ini?

Ini adalah contoh baris dari satu file:

^@F^@i^@l^@e^@n^@a^@m^@e^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@:^@ ^@^M^@
mrt181
sumber

Jawaban:

51

Kamu bisa mencoba:

  • %s/<CTRL-2>//g (pada PC biasa)

  • %s/<CTRL-SHIFT-2>//g (pada PC Mac)

di mana <CTRL-2>berarti pertama kali menekan CTRLPC biasa, menjaganya tetap ditekan, tekan 2, lepaskan CTRL.

dan <CTRL-SHIFT-2>berarti pertama-tama tekan ke bawah controlpada PC Mac, jaga agar ditekan, tekan shiftpada PC Mac, jaga agar ditekan, tekan 2, lepaskan controldan shift.

Akhirnya, kedua perintah harus menghasilkan di %s/^@//glayar. ^@berarti karakter tunggal (byte NULL, yang sebaliknya tidak dapat ditampilkan), tidak ^diikuti oleh @, jadi Anda tidak bisa mengetik ^dan @berturut-turut dalam perintah di atas.

Perintah ini menghapus semua ^@.

phresus
sumber
4
Baru saja menemukan pertanyaan / jawaban ini melalui tautan terkait: Ini sebenarnya saran yang buruk dan hanya akan berfungsi dengan baik dalam beberapa kasus. Lebih baik mengubah encoding daripada menghapus byte kosong. Jika Anda menghapus byte nol, Anda mungkin masih memiliki karakter multibyte lain yang muncul sebagai sampah.
Mario
@ Mario dapatkah Anda memberi tahu kami lebih banyak tentang perubahan penyandian? Apakah ini terkait dengan jawaban jrb di bawah ini?
George
Lihat jawaban rpyzh lebih jauh di bawah. Menunjukkan memuat file menggunakan pengkodean yang tepat serta menyimpannya dengan yang berbeda (walaupun jawabannya mungkin perlu penjelasan lebih lanjut). Catatan terakhir Jrb sudah cukup jika Anda hanya ingin membacanya, tetapi tidak jika Anda ingin menyimpannya tanpa byte nol menggunakan pengodean lain.
Mario
50

Saya tidak berpikir file Anda rusak. Baris contoh Anda sepertinya berisi teks biasa dengan byte nol di antara setiap karakter. Ini menunjukkan bahwa ini adalah file teks yang telah dikodekan dalam UTF-16 tetapi tanda byte-order tidak ada sejak awal file. Lihat http://en.wikipedia.org/wiki/Byte-order_mark

Misalkan saya membuka Notepad, ketik kata 'filename', dan simpan sebagai Unicode Big-endian. Tumpukan hex file ini terlihat seperti ini:

fe ff 00 66 00 69 00 6c 00 65 00 6e 00 61 00 6d 00 65

Jika saya membuka file ini di Vim terlihat baik - byte 'fe ff' memberi tahu Vim bagaimana file dikodekan. Sekarang anggaplah saya membuat file yang berisi urutan byte yang sama persis, tetapi tanpa 'fe ff' terkemuka. Sisipan Vim ^ @ (atau <00>, tergantung pada konfigurasi Anda), menggantikan byte nol; Notepad menyisipkan spasi.

Jadi daripada menghapus nulls, Anda harus benar-benar mencari untuk mendapatkan Vim untuk menafsirkan file dengan benar. Anda bisa meminta Vim memuat ulang file dengan penyandian yang benar dengan perintah:

:e ++enc=utf16

jrb
sumber
Ya, perintah terakhir yang dibuat vim menafsirkan file dengan benar tetapi tidak menghapus nullbytes.
mrt181
6
Untuk menghapusnya, pilih penyandian lain dan simpan kembali file:: set fenc = utf-8
scy
35

Ini sebenarnya bekerja untuk saya dalam vim:

:%s/\%x00//g
jriggins
sumber
5
ini bekerja dengan substitusi (), tetapi Ctl-VCtl-Shift-2 tidak.
dsummersl
Masalah yang sama bagi saya, saya juga tidak bisa <Ctrl-V><Ctrl-2>(dan juga yang <Ctrl-Shift-2>bekerja), tetapi ini berhasil.
Jeff Bridgman
5
Ini berfungsi untuk saya linux. '00' adalah nilai hex ASCII, yang dapat Anda temukan untuk karakter apa pun di vim dengan menempatkan kursor di atasnya dan mengetikkan 'ga' (pikirkan "get ascii) dalam mode perintah atau: as /: ascii pada baris perintah. Vim .wikia.com / wiki / ...
Casey Jones
^ Vx00 juga berfungsi. Anda juga dapat memasukkan 16-bit unicode dengan ^ VuXXXX. Saya mencoba \% uXXXX dalam pencarian dan itu juga berhasil.
Edward Falk
Anda akan menjadi orang yang saya cintai sampai akhir zaman. Dari lubuk hatiku ... terima kasih!
Gonzalo Cao
12

'Simbol' itu mewakili karakter NULL, dengan nilai ASCII 000.

Sulit untuk menghapus dengan vim, coba

tr -d '\000' < file1 > file2
pavium
sumber
7

Seperti yang telah dicatat orang lain, itu adalah byte nol (ASCII 00). Di Linux, cara memasukkan nilai ASCII ke vim adalah dengan menekan Ctrl-V diikuti dengan nilai oktal 3 digit dari karakter apa pun. Untuk mengganti semua byte nol, gunakan:

    :%s/Ctrl-V000//g

(tanpa spasi).

Anda juga dapat mencari nulls dengan:

    /Ctrl-V000

Dalam kedua kasus, itu tidak akan menampilkan nol saat Anda mengetik, tetapi setelah memasukkan ketiganya, itu akan ditampilkan ^@. Pada terminal warna itu akan menunjukkan bahwa dengan warna biru untuk menunjukkan bahwa itu adalah karakter kontrol.

TheAmigo
sumber
6

FWIW, dalam kasus saya, saya harus menggunakan vim di cygwin untuk mengedit file teks yang dibuat pada mac. Solusi yang diterima tidak bekerja untuk saya, tetapi sudah dekat. Menurut halaman wiki Vim tentang bekerja dengan Unicode , ada perbedaan antara versi Big Endian dan Little Endian dari byte BOM. Jadi, saya harus secara eksplisit mengatakan vimuntuk menggunakan versi Little BOM encoding BOM.

Hanya setelah memilih pengkodean yang tepat saya mengkonversi format file (akhiran garis) dossehingga saya dapat mengedit file di Windows editor. Mencoba mengatur ulang format file sebelum menentukan pengkodean memberi saya kesedihan. Ini daftar lengkap perintah yang saya gunakan:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq
rpyzh
sumber
Info berharga Dalam kasus saya itu adalah endianness dari byte BOM.
Andre Albuquerque
3

Solusi yang diterima tidak berhasil untuk saya. Saya membuat vim mem-pipe file melalui trgantinya:

:%!tr -d '\000'

Ini juga akan bekerja dengan baik dengan mode visual (cukup ketik :!tr -d '\000') atau pada berbagai baris:

# Remove nulls from current line:
:.!tr -d '\000'

# Remove nulls from lines 3-5:
:3,5!tr -d '\000'
jnylen
sumber
2

^@ bukan karakter buruk jika Anda menggunakan penyandian yang tepat, tetapi jika Anda ingin menghapusnya maka cobalah:

  • tr -d '\000'
  • sed 's/\000//g'

^ Karakter M ada dalam data contoh Anda

Untuk mengonversi file Anda ke format Unix / Linux sebelum pemrosesan apa pun, coba:

dos2unix filename - rhel dan lainnya

dos2ux filename [newfilename] - HP-UX

pengguna490343
sumber
1

Selain jawaban @ jrb, di Vim, pengkodean karakter file terdeteksi berdasarkan opsi fileencodings. (catat 's' di akhir fileencodings)

Yaitu pada Windows, nilai default untuk fileencodingsopsi adalah ucs-bom, yang berarti:

periksa apakah BOM ada di awal file.

Jika BOM ada, maka 'baca karakter pengkodean file keluar dari BOM'.

Jika BOM tidak ada (dan dalam hal ini juga berarti bahwa semua penyandian karakter yang ditentukan dalam fileencodingsopsi gagal cocok), maka baca file dengan penyandian karakter yang ditentukan dalam encodingopsi. Karakter pengkodean default untuk encodingpilihan adalah: latin1. Sekarang, karena latin1adalah pengkodean karakter satu byte panjang, semua byte dalam file adalah latin1karakter yang valid (bahkan Nulkarakter ^@yang Anda lihat *).

* - sebenarnya, ^@adalah karakter baris baru dalam teks buffer Vim, bukan karakter Nul.

Cara yang tepat untuk membaca file adalah dengan menentukan pengkodean karakter secara manual sebagai UTF-16 (seperti UTF-16 adalah pengkodean karakter yang tepat dalam kasus ini).

colemik
sumber