Mengidentifikasi dan menghapus karakter nol di UNIX

98

Saya memiliki file teks yang berisi karakter null yang tidak diinginkan (ASCII NUL, \0). Ketika saya mencoba untuk melihatnya di visaya melihat ^@simbol, disisipkan dalam teks normal. Bagaimana bisa saya:

  1. Identifikasi baris mana dalam file yang berisi karakter null? Saya telah mencoba grepping for \0dan \x0, tetapi ini tidak berhasil.

  2. Hapus karakter nol? Menjalankan stringsfile membersihkannya, tetapi saya hanya ingin tahu apakah ini cara terbaik?

dogbane
sumber
1
Pertanyaan semacam ini mungkin milik SuperUser.com
Olivier Lalonde
2
Faktanya, pertanyaan ini ada di superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
jrb

Jawaban:

130

Saya akan menggunakan tr:

tr < file-with-nulls -d '\000' > file-without-nulls

Jika Anda bertanya-tanya apakah pengalihan input di tengah argumen perintah berfungsi, itu berhasil. Kebanyakan kerang akan mengenali dan menangani I / O redirection ( <, >, ...) di mana saja di baris perintah, sebenarnya.

Runcing
sumber
dan "file diff-with-nulls file-without-nulls" harus menunjukkan kepada saya baris mana yang memiliki karakter null? Ini membawa kembali lebih banyak dari yang diharapkan.
dogbane
10
Sebenarnya, saya percaya itu harus tr -d '\000' < file-with-nulls > file-without-nullskarena <merupakan bagian dari fungsi pipa shell dan bukan tr.
Mikael S
9
Kebanyakan shell akan mengenali & menangani <atau> di manapun dalam string argumen, sebenarnya. Aku juga kaget.
pra
1
+1 Untuk penggunaan pengalihan input sebagai ganti cat |. Solusi yang bagus dan bersih dan memecahkan masalah saya.
Krzysztof Jabłoński
4
@Pointy '\ 000' digunakan sebagai pengganti '\ 0' dalam spesifikasi grup terbuka POSIX untuk tr. Itulah alasan yang bagus untuk memilihnya
Harold Fischer
68

Gunakan perintah sed berikut untuk menghapus karakter null dalam file.

sed -i 's/\x0//g' null.txt

solusi ini mengedit file di tempatnya, penting jika file tersebut masih digunakan. meneruskan -i'ext 'membuat cadangan file asli dengan akhiran' ext 'ditambahkan.

rekha_sri
sumber
6
Catatan: Di FreeBSD (dan saya percaya juga Mac OS X), sed -i membutuhkan ekstensi di argumen berikutnya, tetapi mungkin kosong. Dalam sistem-sistem, menambahkan '', seperti dalam: sed -i '' 's/\x0//g "$FILE".
Tim Čas
1
Ini urutan besarnya lebih cepat dari trpada saya
diachedelic
Bagi saya, menggunakan Git untuk Windows dan $ sed --version-> sed (GNU sed) 4.7, saya harus menggunakan permintaan berikut untuk mendapatkan file cadangan yang disebut example.csv.bak:sed -i.bak 's/\x0//g' example.csv
Andrew Keeton
1
@ TimČas Anda melakukannya dengan hebat, baru saja melewatkan satu 'jadi seharusnya sed -i' '' s / \ x0 // g 'some_file.xml
Darko
@Darko Jadi saya lakukan. Ups.
Tim Čas
22

Sejumlah besar karakter NUL yang tidak diinginkan, katakanlah satu setiap byte lainnya, menunjukkan bahwa file tersebut dikodekan dalam UTF-16 dan yang harus Anda gunakan iconvuntuk mengubahnya menjadi UTF-8.

Ignacio Vazquez-Abrams
sumber
1
Saya kehabisan ruang disk saat aplikasi saya masuk. Ini menghasilkan karakter-karakter ini.
dogbane
Sebagai contoh, ia bekerja menggunakan perintah ini: iconv -f UTF-16 -t UTF-8 file.
djule5
7

Saya menemukan yang berikut ini, yang mencetak baris mana, jika ada, yang memiliki karakter nol:

perl -ne '/\000/ and print;' file-with-nulls

Juga, oktal dump dapat memberi tahu Anda jika ada nulls:

od file-with-nulls | grep ' 000'
dogbane
sumber
5

Jika baris pada file diakhiri dengan \ r \ n \ 000 maka yang berhasil adalah menghapus \ n \ 000 lalu ganti \ r dengan \ n.

tr -d '\n\000' <infile | tr '\r' '\n' >outfile
wwmbes.dll
sumber
PS. Jika Anda berada dalam shell Windows DOS, Anda bisa mendapatkan perintah Unix versi GNU / win32 dari Sourceforge.net. Saya menggunakannya sepanjang waktu. Lihat "od" perintah oktal dump untuk menganalisis apa yang ada dalam file ...
wwmbes
2

Berikut adalah contoh cara menghapus karakter NULL menggunakan ex(di tempat):

ex -s +"%s/\%x00//g" -cwq nulls.txt

dan untuk banyak file:

ex -s +'bufdo!%s/\%x00//g' -cxa *.txt

Untuk rekursif, Anda dapat menggunakan opsi globbing **/*.txt (jika didukung oleh shell Anda).

Berguna untuk skrip karena sed dan -iparameternya adalah ekstensi BSD non-standar.

Lihat juga: Bagaimana cara memeriksa apakah file tersebut adalah file biner dan membaca semua file yang bukan?

kenorb
sumber
1

Saya menggunakan:

recode UTF-16..UTF-8 <filename>

untuk menghilangkan angka nol dalam file.

logisec
sumber
0

Saya menghadapi kesalahan yang sama dengan:

import codecs as cd
f=cd.open(filePath,'r','ISO-8859-1')

Saya memecahkan masalah dengan mengubah pengkodean menjadi utf-16

f=cd.open(filePath,'r','utf-16')
Ming Young
sumber