การระบุและลบอักขระว่างใน UNIX


100

ฉันมีไฟล์ข้อความที่มีอักขระว่างที่ไม่ต้องการ (ASCII NUL, \0) เมื่อฉันพยายามเปิดดูในviฉันเห็น^@สัญลักษณ์แทรกอยู่ในข้อความปกติ ฉันสามารถ:

  1. ระบุว่าบรรทัดใดในไฟล์มีอักขระ null? ฉันได้ลองใช้ grepping \0และ\x0แต่ไม่ได้ผล

  2. ลบอักขระว่าง? การทำงานstringsบนไฟล์จะล้างข้อมูล แต่ฉันแค่สงสัยว่านี่เป็นวิธีที่ดีที่สุดหรือไม่?


1
คำถามแบบนี้น่าจะเป็นของ SuperUser.com
Olivier Lalonde

2
อันที่จริงคำถามนี้อยู่ใน superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
jrb

คำตอบ:


131

ฉันจะใช้tr:

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

หากคุณสงสัยว่าการเปลี่ยนทิศทางอินพุตตรงกลางอาร์กิวเมนต์คำสั่งใช้งานได้หรือไม่ เปลือกหอยส่วนใหญ่จะรับรู้และจัดการกับ I / O เปลี่ยนเส้นทาง ( <, >, ... ) ที่ใดก็ได้ในบรรทัดคำสั่งจริง


10
อันที่จริงผมเชื่อว่ามันควรจะเป็นtr -d '\000' < file-with-nulls > file-without-nullsตั้งแต่เป็นส่วนหนึ่งของการทำงานของท่อเปลือกและไม่< tr
Mikael S

9
เชลล์ส่วนใหญ่จะรับรู้และจัดการกับ <หรือ> ที่ใดก็ได้ในสตริงอาร์กิวเมนต์ ทำให้ฉันประหลาดใจเช่นกัน
พระ

1
+1 cat |สำหรับการใช้งานของการเปลี่ยนเส้นทางการป้อนข้อมูลแทน วิธีแก้ปัญหาที่ดีและสะอาดและช่วยแก้ปัญหาของฉันได้
Krzysztof Jabłoński

1
นี่เป็นลำดับขนาดที่ช้ากว่าsedสำหรับฉัน
diachedelic

4
@Pointy '\ 000' ใช้แทน '\ 0' ในข้อกำหนดของ POSIX opengroup สำหรับ tr นั่นเป็นเหตุผลที่ดีที่จะชอบ
Harold Fischer

68

ใช้คำสั่ง sed ต่อไปนี้เพื่อลบอักขระ null ในไฟล์

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

โซลูชันนี้จะแก้ไขไฟล์ในตำแหน่งที่สำคัญหากยังคงใช้ไฟล์อยู่ ผ่าน -i'ext 'สร้างการสำรองข้อมูลของไฟล์ต้นฉบับโดยเพิ่มคำต่อท้าย' ext '


6
หมายเหตุ: ใน FreeBSD (และฉันเชื่อว่า Mac OS X ด้วย) sed -i ต้องการส่วนขยายในอาร์กิวเมนต์ถัดไป แต่อาจว่างเปล่า ในระบบที่เพิ่มเช่น:'' sed -i '' 's/\x0//g "$FILE"
Tim Čas

2
นี่เป็นลำดับขนาดที่เร็วกว่าtrสำหรับฉัน
diachedelic

สำหรับผมใช้ Git สำหรับ Windows และ$ sed --version-> sed (GNU sed) 4.7ผมต้องใช้การภาวนาต่อไปนี้จะได้รับแฟ้มสำรองข้อมูลที่เรียกว่าexample.csv.bak:sed -i.bak 's/\x0//g' example.csv
แอนดรู Keeton

1
@ TimČasคุณทำได้ดีมากพลาดเพียงครั้งเดียว 'ดังนั้นจึงควร sed -i' 's / \ x0 // g' some_file.xml
Darko

@Darko ฉันก็เลยทำ อ๊ะ.
Tim Čas

22

อักขระ NUL ที่ไม่ต้องการจำนวนมากพูดทีละไบต์แสดงว่าไฟล์เข้ารหัสเป็น UTF-16 และคุณควรใช้iconvเพื่อแปลงเป็น UTF-8


1
ฉันไม่มีพื้นที่ว่างในดิสก์ในขณะที่แอปพลิเคชันของฉันกำลังบันทึก ส่งผลให้ตัวละครเหล่านี้
dogbane

ตัวอย่างเช่นมันทำงานโดยใช้คำสั่งนี้: iconv -f UTF-16 -t UTF-8 file.
djule5

7

ฉันค้นพบสิ่งต่อไปนี้ซึ่งพิมพ์ว่าบรรทัดใดมีอักขระว่าง:

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

นอกจากนี้การถ่ายโอนข้อมูลฐานแปดสามารถบอกคุณได้ว่ามีค่าว่างหรือไม่:

od file-with-nulls | grep ' 000'

5

หากบรรทัดในไฟล์ลงท้ายด้วย \ r \ n \ 000 สิ่งที่ใช้ได้ผลคือการลบ \ n \ 000 จากนั้นแทนที่ \ r ด้วย \ n

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

ปล. หากคุณพบว่าตัวเองอยู่ในเชลล์ Windows DOS คุณสามารถรับคำสั่ง Unix เวอร์ชัน GNU / win32 ได้จาก Sourceforge.net ฉันใช้มันตลอดเวลา ตรวจสอบ "od" คำสั่งการถ่ายโอนข้อมูลฐานแปดสำหรับการวิเคราะห์สิ่งที่อยู่ในไฟล์ ...
wwmbes

3

นี่คือตัวอย่างวิธีการลบอักขระ NULL โดยใช้ex(in-place):

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

และสำหรับหลายไฟล์:

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

สำหรับการเรียกซ้ำคุณอาจใช้ตัวเลือก globbing **/*.txt (หากเชลล์ของคุณรองรับ)

มีประโยชน์สำหรับการเขียนสคริปต์ตั้งแต่นั้นเป็นต้นมาsed และ-iพารามิเตอร์คือส่วนขยาย BSD ที่ไม่ได้มาตรฐาน

ดูเพิ่มเติม: จะตรวจสอบได้อย่างไรว่าไฟล์นั้นเป็นไฟล์ไบนารีและอ่านไฟล์ทั้งหมดที่ไม่ใช่?



0

ฉันประสบกับข้อผิดพลาดเดียวกันกับ:

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

ฉันแก้ปัญหาโดยเปลี่ยนการเข้ารหัสเป็น utf-16

f=cd.open(filePath,'r','utf-16')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.