Identyfikowanie i usuwanie znaków null w systemie UNIX

99

Mam plik tekstowy zawierający niechciane znaki null (ASCII NUL, \0). Kiedy próbuję to zobaczyć, viwidzę ^@symbole przeplatane zwykłym tekstem. Jak mogę:

  1. Zidentyfikować, które wiersze w pliku zawierają znaki puste? Próbowałem grepować dla \0i \x0, ale to nie zadziałało.

  2. Usunąć znaki puste? Uruchomienie stringsna pliku wyczyściło go, ale zastanawiam się tylko, czy to najlepszy sposób?

dogbane
źródło
1
Tego rodzaju pytanie prawdopodobnie należy do SuperUser.com
Olivier Lalonde
2
W rzeczywistości to pytanie jest na superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
jrb

Odpowiedzi:

132

Użyłbym tr:

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

Jeśli zastanawiasz się, czy przekierowanie wejścia w środku argumentów poleceń działa, to działa. Większość muszle będą rozpoznawać i radzić sobie z I / O przekierowania ( <, >...) w dowolnym miejscu w wierszu poleceń, faktycznie.

Spiczasty
źródło
a "diff file-with-nulls file-without-nulls" powinien pokazać mi, które wiersze miały puste znaki? Przynosi o wiele więcej niż oczekiwano.
zgubiony
10
Właściwie uważam, że powinno tak być, tr -d '\000' < file-with-nulls > file-without-nullsponieważ <jest częścią funkcji rury powłoki, a nie tr.
Mikael S
9
Większość powłok rozpoznaje i radzi sobie z <lub> w dowolnym miejscu argumentu. Mnie też zdziwiłem.
dniu
1
+1 Do użycia przekierowania wejścia zamiast cat |. Dobre, czyste rozwiązanie i rozwiązało mój problem.
Krzysztof Jabłoński
4
@Pointy '\ 000' jest używane zamiast '\ 0' w specyfikacji POSIX opengroup dla tr. To dobry powód, żeby go preferować
Harold Fischer
68

Użyj następującego polecenia sed, aby usunąć znaki null z pliku.

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

to rozwiązanie edytuje plik w miejscu, co jest ważne, jeśli plik jest nadal używany. przekazanie -i'ext 'tworzy kopię zapasową oryginalnego pliku z dodanym przyrostkiem' ext '.

rekha_sri
źródło
6
Uwaga: We FreeBSD (i myślę, że także Mac OS X) sed -i wymaga rozszerzenia w następnym argumencie, ale może być puste. W tych systemach, dodać '', na przykład: sed -i '' 's/\x0//g "$FILE".
Tim Čas
1
To o rząd wielkości szybciej niż trdla mnie
diachedelic
Dla mnie, używając Git dla Windows i $ sed --version-> sed (GNU sed) 4.7, musiałem użyć następującego wywołania, aby uzyskać plik kopii zapasowej o nazwie example.csv.bak:sed -i.bak 's/\x0//g' example.csv
Andrew Keeton
1
@ TimČ, bo zrobiłeś to świetnie, właśnie przegapiłem jeden 'więc powinien być sed -i' '' s / \ x0 // g 'some_file.xml
Darko
@Darko Tak zrobiłem. Ups.
Tim Čas
22

Duża liczba niechcianych znaków NUL, powiedzmy jeden co drugi bajt, wskazuje, że plik jest zakodowany w UTF-16 i że należy go użyć iconvdo konwersji do UTF-8.

Ignacio Vazquez-Abrams
źródło
1
Skończyło mi się miejsce na dysku podczas logowania aplikacji. Spowodowało to te postacie.
zgubienie psów
Na przykład, działa za pomocą polecenia: iconv -f UTF-16 -t UTF-8 file.
djule5
7

Odkryłem następujące, które wypisuje, które wiersze, jeśli w ogóle, mają znaki puste:

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

Ponadto zrzut ósemkowy może powiedzieć, czy występują wartości null:

od file-with-nulls | grep ' 000'
dogbane
źródło
5

Jeśli wiersze w pliku kończą się na \ r \ n \ 000, to działa usunięcie \ n \ 000, a następnie zastąpienie \ r \ n.

tr -d '\n\000' <infile | tr '\r' '\n' >outfile
wwmbes
źródło
PS. Jeśli znajdziesz się w powłoce Windows DOS, możesz pobrać wersje poleceń Unix w wersji GNU / win32 ze strony Sourceforge.net. Używam ich cały czas. Sprawdź "od" polecenie zrzutu ósemkowego do analizy zawartości pliku ...
wwmbes
2

Oto przykład, jak usunąć znaki NULL za pomocą ex(w miejscu):

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

i dla wielu plików:

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

Dla rekurencyjności możesz użyć opcji globbingu **/*.txt (jeśli jest obsługiwana przez twoją powłokę).

Przydatne do tworzenia skryptów, ponieważ sed jego -iparametr jest niestandardowym rozszerzeniem BSD.

Zobacz też: Jak sprawdzić, czy plik jest plikiem binarnym i czytać wszystkie pliki, które nim nie są?

kenorb
źródło
1

Użyłem:

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

aby pozbyć się zer w pliku.

logisec
źródło
0

Napotkałem ten sam błąd z:

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

Rozwiązałem problem, zmieniając kodowanie na utf-16

f=cd.open(filePath,'r','utf-16')
Ming Young
źródło