Nhận dạng và xóa các ký tự rỗng trong UNIX


98

Tôi có một tệp văn bản chứa các ký tự rỗng không mong muốn (ASCII NUL, \0). Khi tôi cố gắng xem nó trong vitôi thấy ^@các biểu tượng, được xen kẽ trong văn bản bình thường. Làm thế nào tôi có thể:

  1. Xác định dòng nào trong tệp chứa các ký tự rỗng? Tôi đã thử tìm kiếm \0\x0nhưng điều này không hiệu quả.

  2. Xóa các ký tự rỗng? Chạy stringstrên tệp đã làm sạch nó, nhưng tôi chỉ tự hỏi liệu đây có phải là cách tốt nhất không?


1
Đây là loại câu hỏi có lẽ thuộc về SuperUser.com
Olivier Lalonde

2
Trong thực tế, câu hỏi này là về superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
JRB

Câu trả lời:


130

Tôi muốn sử dụng tr:

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

Nếu bạn đang tự hỏi liệu chuyển hướng đầu vào ở giữa các đối số lệnh có hoạt động hay không, thì nó sẽ đúng. Hầu hết vỏ sẽ nhận biết và đối phó với I / O chuyển hướng ( <, >, ...) bất cứ nơi nào trong dòng lệnh, trên thực tế.


và "diff file-with-nulls file-without-nulls" sẽ cho tôi biết dòng nào có ký tự rỗng? Nó mang lại rất nhiều điều hơn mong đợi.
dogbane

10
Trên thực tế, tôi tin rằng nó phải được tr -d '\000' < file-with-nulls > file-without-nullskể từ khi <là một phần của chức năng ống vỏ và không tr.
Mikael S

9
Thực ra, hầu hết các shell sẽ nhận ra và xử lý <hoặc> ở bất kỳ đâu trong chuỗi đối số. Tôi cũng ngạc nhiên.
pra

1
+1 Để sử dụng chuyển hướng đầu vào thay vì cat |. Một giải pháp tốt, sạch sẽ và nó đã giải quyết được vấn đề của tôi.
Krzysztof Jabłoński

4
@Pointy '\ 000' được sử dụng thay cho '\ 0' trong đặc tả nhóm openg POSIX cho tr. Đó là lý do chính đáng để bạn thích nó
Harold Fischer,

67

Sử dụng lệnh sed sau đây để xóa các ký tự rỗng trong tệp.

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

giải pháp này chỉnh sửa tệp tại chỗ, điều quan trọng là nếu tệp vẫn đang được sử dụng. pass -i'ext 'tạo một bản sao lưu của tệp gốc có thêm hậu tố' ext '.


6
Lưu ý: Trong FreeBSD (và tôi tin rằng cả Mac OS X), sed -i yêu cầu một phần mở rộng trong đối số tiếp theo, nhưng nó có thể trống. Trong những hệ thống, thêm một '', như trong: sed -i '' 's/\x0//g "$FILE".
Tim Čas

1
Đây là một thứ tự cường độ nhanh hơn trđối với tôi
diachedelic

Đối với tôi, bằng cách sử dụng Git cho Windows và $ sed --version-> sed (GNU sed) 4.7, tôi phải sử dụng lời gọi sau để nhận tệp sao lưu có tên example.csv.bak:sed -i.bak 's/\x0//g' example.csv
Andrew Keeton

1
@ TimČas bạn đã làm rất tốt, chỉ cần bỏ lỡ một 'vì vậy nó phải là sed -i' 's / \ x0 // g' some_file.xml
Darko

@Darko Vì vậy, tôi đã làm. Giáo sư.
Tim Čas

22

Một số lượng lớn các ký tự NUL không mong muốn, chẳng hạn như mỗi byte khác, cho biết rằng tệp được mã hóa bằng UTF-16 và bạn nên sử dụng iconvđể chuyển đổi nó thành UTF-8.


1
Tôi đã hết dung lượng ổ đĩa khi ứng dụng của tôi đang ghi nhật ký. Điều này dẫn đến các ký tự này.
dogbane

Ví dụ, nó hoạt động sử dụng lệnh này: iconv -f UTF-16 -t UTF-8 file.
djule

7

Tôi đã phát hiện ra những điều sau đây, in ra những dòng nào, nếu có, có ký tự rỗng:

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

Ngoài ra, một kết xuất bát phân có thể cho bạn biết nếu có null:

od file-with-nulls | grep ' 000'

5

Nếu các dòng trong tệp kết thúc bằng \ r \ n \ 000 thì cách hiệu quả là xóa \ n \ 000 sau đó thay thế \ r bằng \ n.

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

Tái bút. Nếu bạn thấy mình đang ở trong Windows DOS shell, bạn có thể lấy phiên bản GNU / win32 của lệnh Unix từ Sourceforge.net. Tôi sử dụng tất cả các thời gian. Kiểm tra "od" lệnh bãi bát phân để phân tích những gì trong một tập tin ...
wwmbes

2

Đây là ví dụ về cách loại bỏ các ký tự NULL bằng cách sử dụng ex (tại chỗ):

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

và cho nhiều tệp:

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

Đối với tính toán đệ quy, bạn có thể sử dụng tùy chọn lấp lánh **/*.txt (nếu nó được hỗ trợ bởi trình bao của bạn).

Hữu ích cho việc viết kịch bản vì sed-itham số của nó là phần mở rộng BSD không chuẩn.

Xem thêm: Làm thế nào để kiểm tra xem tệp có phải là tệp nhị phân và đọc tất cả các tệp không?


1

Tôi đã sử dụng:

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

để loại bỏ các số 0 trong tệp.


0

Tôi gặp phải lỗi tương tự với:

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

Tôi đã giải quyết vấn đề bằng cách thay đổi mã hóa thành utf-16

f=cd.open(filePath,'r','utf-16')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.