UNIX'te boş karakterleri tanımlama ve kaldırma


99

İstenmeyen boş karakterler (ASCII NUL, \0) içeren bir metin dosyam var . İçinde görüntülemeye çalıştığımda , normal metinde araya eklenen semboller vigörüyorum ^@. Nasıl yapabilirim:

  1. Dosyadaki hangi satırların boş karakterler içerdiğini belirle? Ben grepping denedi \0ve \x0ancak bu iş olmadı.

  2. Boş karakterler kaldırılsın mı? stringsDosyada koşmak onu temizledi, ama bunun en iyi yol olup olmadığını merak ediyorum.


1
Bu tür sorular muhtemelen SuperUser.com'a ait
Olivier Lalonde

Yanıtlar:


132

Kullanırım tr:

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

Komut argümanlarının ortasındaki giriş yeniden yönlendirmenin işe yarayıp yaramadığını merak ediyorsanız, işe yarıyor. Çoğu kabukları tanımak ve I ilgilenecek / O yönlendirmesi ( <, >, ...) her yerde aslında komut satırında, içinde.


ve bir "diff-file-with-nulls file-without-nulls" bana hangi satırların boş karakterlere sahip olduğunu göstermelidir? Beklenenden çok daha fazlasını geri getiriyor.
dogbane

10
Aslında, o tr -d '\000' < file-with-nulls > file-without-nullszamandan beri <kabuk borusu işlevinin bir parçası olması gerektiğine inanıyorum tr.
Mikael S

9
Aslında çoğu kabuk, argüman dizesinin herhangi bir yerinde <veya> ile ilgilenecek ve ilgilenecektir. Beni de şaşırttı.
pra

1
+1 yerine giriş yönlendirme kullanımı için cat |. Güzel, temiz bir çözüm ve sorunumu çözdü.
Krzysztof Jabłoński

4
Tr için POSIX açık grup belirtiminde '\ 0' yerine @Pointy '\ 000' kullanılır. Bu, onu tercih etmek için iyi bir neden
Harold Fischer

68

Bir dosyadaki boş karakterleri kaldırmak için aşağıdaki sed komutunu kullanın.

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

bu çözüm, dosyayı yerinde düzenler, dosya hala kullanılıyorsa önemlidir. -i'ext 'geçmek,' ext 'soneki eklenmiş orijinal dosyanın bir yedeğini oluşturur.


6
Not: FreeBSD'de (ve ayrıca Mac OS X'e inanıyorum), bir sonraki argümanda bir uzantı sed -i gerektirir , ancak boş olabilir. Bu sistemlerde, bir ekleme ''olduğu gibi: sed -i '' 's/\x0//g "$FILE".
Tim Čas

1
Bu trbenden daha hızlı bir sıra
diachedelic

Benim için, Windows için Git'i ve $ sed --version-> sed (GNU sed) 4.7, adında bir yedekleme dosyası almak için aşağıdaki çağrıyı kullanmak zorunda kaldım example.csv.bak:sed -i.bak 's/\x0//g' example.csv
Andrew Keeton

1
@ TimČ harika yaptın, sadece birini kaçırdın, bu yüzden sed -i '' 's / \ x0 // g' some_file.xml
Darko

@Darko Ben de yaptım. Oops.
Tim

22

Çok sayıda istenmeyen NUL karakteri, örneğin her bayt, dosyanın UTF-16 olarak kodlandığını ve iconvonu UTF-8'e dönüştürmek için kullanmanız gerektiğini gösterir.


1
Uygulamam günlüğe kaydedilirken disk alanım bitti. Bu, bu karakterlerle sonuçlanır.
dogbane

Örneğin, bu komutu kullanarak çalışır: iconv -f UTF-16 -t UTF-8 file.
djule5

7

Aşağıdakileri keşfettim, hangi satırların, varsa, boş karakterlere sahip olduğunu yazdırıyorum:

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

Ayrıca, sekizlik bir döküm size boş değerler olup olmadığını söyleyebilir:

od file-with-nulls | grep ' 000'

5

Dosyadaki satırlar \ r \ n \ 000 ile bitiyorsa, işe yarayan şey \ n \ 000'i silmek ve ardından \ r'yi \ n ile değiştirmektir.

tr -d '\n\000' <infile | tr '\r' '\n' >outfile

PS. Kendinizi bir Windows DOS kabuğunda bulursanız, Sourceforge.net'ten Unix komutlarının GNU / win32 sürümlerini alabilirsiniz. Onları her zaman kullanıyorum. Bir dosyada ne olduğunu analiz etmek için sekizlik döküm komutuna "od" göz atın ...
wwmbes

2

NULL karakterlerin ex(yerinde) kullanılarak nasıl kaldırılacağına dair bir örnek :

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

ve birden çok dosya için:

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

Özyinelemeli için, globbing seçeneğini kullanabilirsiniz **/*.txt(eğer kabuğunuz tarafından destekleniyorsa).

Komut dosyası için kullanışlıdır sed ve -iparametresi standart olmayan bir BSD uzantısıdır.

Ayrıca bakınız: Dosyanın ikili dosya olup olmadığı nasıl kontrol edilir ve olmayan tüm dosyalar nasıl okunur?


1

Kullandım:

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

dosyadaki sıfırlardan kurtulmak için.


0

Aynı hatayla karşılaştım:

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

Kodlamayı şu şekilde değiştirerek sorunu çözdüm: utf-16

f=cd.open(filePath,'r','utf-16')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.