จะลบสัญลักษณ์นี้“ ^ @” ด้วยเสียงเรียกเข้าได้อย่างไร?


59

ฉันมีไฟล์บางไฟล์ที่เสียหายด้วยสัญลักษณ์นี้:

^ @

มันไม่ได้เป็นส่วนหนึ่งของสตริง มันไม่สามารถค้นหาได้ ฉันจะแทนที่สัญลักษณ์นี้โดยไม่มีอะไรได้อย่างไรหรือฉันจะลบสัญลักษณ์นี้ได้อย่างไร

นี่คือตัวอย่างบรรทัดจากไฟล์เดียว:

^@F^@i^@l^@e^@n^@a^@m^@e^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@:^@ ^@^M^@

คำตอบ:


51

คุณสามารถลอง:

  • %s/<CTRL-2>//g (สำหรับพีซีทั่วไป)

  • %s/<CTRL-SHIFT-2>//g (บนเครื่องพีซี Mac)

ที่<CTRL-2>หมายแรกกดลงCTRLบนเครื่องพีซีปกติทำให้มันกดลงตีปล่อย2CTRL

และ<CTRL-SHIFT-2>หมายถึงการกดครั้งแรกลงcontrolในเครื่องคอมพิวเตอร์ Mac, ทำให้มันกดลงกดลงshiftบนเครื่องพีซีของ Mac, ทำให้มันกดลงตี2ปล่อยและcontrolshift

ในที่สุดทั้งสองคำสั่งควรส่งผลให้%s/^@//gบนหน้าจอ ^@หมายถึงอักขระตัวเดียว (ไบต์ NULL ซึ่งไม่สามารถแสดงได้) ไม่^ตามด้วย@ดังนั้นคุณจึงไม่สามารถพิมพ์^และ@เรียงแถวในคำสั่งด้านบนได้

^@คำสั่งนี้จะลบทั้งหมด


4
เพิ่งสะดุดกับคำถาม / คำตอบผ่านลิงก์ที่เกี่ยวข้อง: นี่เป็นคำแนะนำที่ไม่ดีและจะทำงานได้อย่างถูกต้องในบางกรณีเท่านั้น เป็นการดีกว่าที่จะเปลี่ยนการเข้ารหัสจริงมากกว่าการลบ null ไบต์ หากคุณลบไบต์ว่างคุณอาจยังมีอักขระหลายไบต์อื่น ๆ ที่แสดงเป็นขยะ
Mario

@Mario คุณสามารถบอกเราเพิ่มเติมเกี่ยวกับการเปลี่ยนการเข้ารหัสได้หรือไม่ มันเกี่ยวข้องกับคำตอบของ jrb ด้านล่างหรือไม่?
George

ดูคำตอบของ rpyzh เพิ่มเติมด้านล่าง แสดงการโหลดไฟล์โดยใช้การเข้ารหัสที่เหมาะสมเช่นเดียวกับการบันทึกด้วยไฟล์อื่น (แม้ว่าคำตอบอาจต้องการคำอธิบายเพิ่มเติม) โน้ตตัวสุดท้ายของ Jrb นั้นเพียงพอแล้วถ้าคุณแค่อยากอ่าน แต่ไม่ใช่ถ้าคุณต้องการให้มันบันทึกโดยไม่ต้องใช้ null ไบต์โดยใช้การเข้ารหัสอื่น
มาริโอ

50

ฉันไม่คิดว่าไฟล์ของคุณเสียหาย บรรทัดตัวอย่างของคุณดูเหมือนว่าจะมีข้อความปกติพร้อมไบต์ว่างระหว่างตัวละครแต่ละตัว สิ่งนี้ชี้ให้เห็นว่าเป็นไฟล์ข้อความที่ถูกเข้ารหัสใน UTF-16 แต่เครื่องหมายคำสั่งไบต์หายไปตั้งแต่เริ่มต้นไฟล์ ดูhttp://en.wikipedia.org/wiki/Byte-order_mark

สมมติว่าฉันเปิด Notepad ให้พิมพ์คำว่า 'ชื่อไฟล์' และบันทึกเป็น Unicode Big-endian ดัมพ์แบบฐานสิบหกของไฟล์นี้มีลักษณะดังนี้:

fe ff 00 66 00 69 00 6c 00 65 00 6e 00 61 00 6d 00 65

ถ้าฉันเปิดไฟล์นี้ใน Vim มันดูดี - ไบต์ 'fe ff' บอก Vim ว่าไฟล์นั้นถูกเข้ารหัสอย่างไร ตอนนี้สมมติว่าฉันสร้างไฟล์ที่มีลำดับไบต์ที่แน่นอนเหมือนกัน แต่ไม่มี 'fe ff' นำหน้า ส่วนที่เป็นกลุ่ม ^ @ (หรือ <00> ขึ้นอยู่กับการกำหนดค่าของคุณ) แทนการใช้ null null; Notepad แทรกช่องว่าง

ดังนั้นแทนที่จะลบค่า Null คุณควรมองหา Vim เพื่อตีความไฟล์อย่างถูกต้อง คุณสามารถรับ Vim เพื่อโหลดไฟล์ใหม่ด้วยการเข้ารหัสที่ถูกต้องด้วยคำสั่ง:

:e ++enc=utf16


ใช่คำสั่งสุดท้ายที่ทำคือ vim ตีความไฟล์อย่างถูกต้อง แต่ไม่ลบ nullbytes
mrt181

6
หากต้องการลบออกให้เลือกการเข้ารหัสอื่นและบันทึกไฟล์อีกครั้ง:: set fenc = utf-8
scy

35

มันใช้งานได้จริงสำหรับฉันภายในกลุ่ม:

:%s/\%x00//g

5
สิ่งนี้ใช้ได้กับ replace () แต่ Ctl-VCtl-Shift-2 ไม่ได้
dsummersl

ปัญหาเดียวกันสำหรับฉันฉันไม่สามารถทำงาน<Ctrl-V><Ctrl-2>(เช่นเดียวกับ<Ctrl-Shift-2>) ด้วยแต่สิ่งนี้ได้ผล
Jeff Bridgman

5
มันใช้งานได้สำหรับฉันลินุกซ์ '00' คือค่าเลขฐานสิบหก ASCII ซึ่งคุณสามารถค้นหาอักขระใด ๆ ในกลุ่มโดยวางเคอร์เซอร์ไว้เหนือและพิมพ์ 'ga' (คิดว่า "get ascii) ในโหมดคำสั่งหรือ: as /: ascii บนบรรทัดคำสั่งvim .wikia.com / wiki / …
Casey Jones

^ Vx00 ยังใช้งานได้ คุณสามารถป้อน Unicode แบบ 16 บิตด้วย ^ VuXXXX ฉันลอง \% uXXXX ในการค้นหาและใช้งานได้
Edward Falk

คุณจะเป็นคนที่ฉันรักจนถึงวันสุดท้าย จากส่วนลึกของหัวใจของฉัน ... ขอบคุณ!
กอนซาโล่เฉา

12

'สัญลักษณ์' นั้นหมายถึงอักขระ NULL ที่มีค่า ASCII 000

มันยากที่จะลบออกเป็นกลุ่มด้วยลอง

tr -d '\000' < file1 > file2

7

ดังที่คนอื่น ๆ ได้กล่าวไว้สิ่งเหล่านั้นคือไบต์ที่ว่างเปล่า (ASCII 00) บน Linux วิธีป้อนค่า ASCII ลงใน vim คือกด Ctrl-V ตามด้วยค่าฐานแปด 3 หลักของอักขระใด ๆ หากต้องการแทนที่ null null ทั้งหมดให้ใช้:

    :%s/Ctrl-V000//g

(ไม่มีช่องว่าง)

ในทำนองเดียวกันคุณสามารถค้นหา nulls ด้วย:

    /Ctrl-V000

ในทั้งสองกรณีมันจะไม่แสดงค่าศูนย์ในขณะที่คุณพิมพ์ แต่หลังจากป้อนทั้งสามแล้วมันจะแสดง^@ขึ้น บนเทอร์มินัลสีมันจะแสดงเป็นสีน้ำเงินเพื่อระบุว่ามันเป็นตัวควบคุม


6

FWIW ในกรณีของฉันฉันต้องใช้ vim บน cygwin เพื่อแก้ไขไฟล์ข้อความที่สร้างขึ้นบน mac ทางออกที่ยอมรับไม่ได้ผลสำหรับฉัน แต่ใกล้เข้ามาแล้ว ตามที่หน้า Vim wiki เกี่ยวกับการทำงานกับ Unicodeมีความแตกต่างระหว่าง Big Endian และ Little Endian รุ่น BOM ไบต์ ดังนั้นฉันต้องบอกvimให้ใช้การเข้ารหัส BOM รุ่น Endian อย่างชัดเจน

หลังจากเลือกการเข้ารหัสที่ถูกต้องแล้วฉันได้แปลงรูปแบบไฟล์ (สิ้นสุดที่บรรทัด) เป็นdosดังนั้นฉันจึงสามารถแก้ไขไฟล์ในตัวแก้ไข Windows พยายามที่จะตั้งค่ารูปแบบไฟล์ก่อนที่จะระบุการเข้ารหัสให้ฉันเสียใจ นี่คือรายการคำสั่งทั้งหมดที่ฉันใช้:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq

ข้อมูลที่มีค่า ในกรณีของฉันมันคือ endianness ของ BOM ไบต์
Andre Albuquerque

3

ทางออกที่ยอมรับไม่ได้ผลสำหรับฉัน ฉันทำ vim pipe ไฟล์ผ่านtrแทน:

:%!tr -d '\000'

สิ่งนี้จะทำงานได้ดีกับโหมดภาพ (แค่พิมพ์:!tr -d '\000') หรือในช่วงของเส้น:

# Remove nulls from current line:
:.!tr -d '\000'

# Remove nulls from lines 3-5:
:3,5!tr -d '\000'

2

^@ ไม่ใช่อักขระที่ไม่ดีถ้าคุณใช้การเข้ารหัสที่เหมาะสม แต่ถ้าคุณต้องการลบให้ลอง:

  • tr -d '\000'
  • sed 's/\000//g'

อักขระ ^ M มีอยู่ในข้อมูลตัวอย่างของคุณ

หากต้องการแปลงไฟล์เป็นรูปแบบ Unix / Linux ก่อนการประมวลผลใด ๆ ให้ลอง:

dos2unix filename - rhel และอื่น ๆ

dos2ux filename [newfilename] - HP-UX


1

นอกเหนือจากคำตอบของ @ jrb ใน Vim การตรวจพบการเข้ารหัสอักขระของไฟล์จะขึ้นอยู่กับตัวเลือก fileencodings (บันทึก 's' ไว้ท้ายไฟล์)

เช่นบน Windows ค่าเริ่มต้นสำหรับfileencodingsตัวเลือกคือucs-bomซึ่งหมายความว่า:

ตรวจสอบว่ามี BOM อยู่ที่จุดเริ่มต้นของไฟล์หรือไม่

หากมี BOM อยู่ให้ 'อ่านการเข้ารหัสอักขระของไฟล์จาก BOM'

หาก BOM ไม่มีอยู่ (และในกรณีนี้ก็หมายความว่าการเข้ารหัสอักขระทั้งหมดที่ระบุในfileencodingsตัวเลือกไม่สามารถจับคู่ได้) ให้อ่านไฟล์ที่มีการเข้ารหัสอักขระที่ระบุในencodingตัวเลือก การเข้ารหัสตัวอักษรเริ่มต้นสำหรับตัวเลือก:encoding latin1ตอนนี้เนื่องจากlatin1เป็นการเข้ารหัสอักขระความยาวหนึ่งไบต์ไบต์ทั้งหมดในไฟล์เป็นlatin1อักขระที่ถูกต้อง(แม้แต่Nulตัวอักษร^@ที่คุณเห็น *)

* - จริง ๆ แล้ว^@คืออักขระขึ้นบรรทัดใหม่ในข้อความบัฟเฟอร์ของ Vim ไม่ใช่อักขระ Nul

วิธีที่เหมาะสมในการอ่านไฟล์คือการระบุการเข้ารหัสอักขระด้วยตนเองเป็น UTF-16 (เพราะดูเหมือนว่า UTF-16 เป็นการเข้ารหัสอักขระที่เหมาะสมในกรณีนี้)

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