Làm thế nào để xóa biểu tượng này ^ ^ ^ với vim?


59

Tôi có một số tệp bị hỏng với biểu tượng này:

^ @

Nó không phải là một phần của chuỗi; nó không thể tìm kiếm được. Làm cách nào để thay thế biểu tượng này bằng không hoặc làm cách nào để xóa biểu tượng này?

Đây là một dòng ví dụ từ một tệp:

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

Câu trả lời:


51

Bạn có thể thử:

  • %s/<CTRL-2>//g (trên PC thông thường)

  • %s/<CTRL-SHIFT-2>//g (trên máy tính Mac)

trong đó <CTRL-2>có nghĩa là trước tiên nhấn xuống CTRLtrên PC thông thường, giữ cho nó như nhấn xuống, nhấn 2, phát hành CTRL.

<CTRL-SHIFT-2>có nghĩa là trước tiên nhấn xuống controlPC Mac, giữ nó như ấn xuống, nhấn xuống shiftPC Mac, giữ nó như nhấn xuống, nhấn 2, phát hành controlshift.

Cuối cùng, cả hai lệnh sẽ dẫn đến %s/^@//gtrên màn hình. ^@có nghĩa là một ký tự đơn (một byte NULL, nếu không được hiển thị), không được ^theo sau @, vì vậy bạn không thể chỉ gõ ^@liên tiếp trong lệnh trên.

Lệnh này loại bỏ tất cả ^@.


4
Chỉ cần vấp phải câu hỏi / câu trả lời này thông qua một liên kết liên quan: Đây thực sự là một lời khuyên tồi và sẽ chỉ hoạt động đúng trong rất ít trường hợp. Tốt hơn là thực sự thay đổi mã hóa thay vì loại bỏ byte rỗng. Nếu bạn loại bỏ các byte rỗng, bạn vẫn có thể có các ký tự đa nhân khác hiển thị dưới dạng rác.
Mario

@Mario bạn có thể cho chúng tôi biết thêm về sự thay đổi mã hóa? Đây có phải là một cái gì đó liên quan đến câu trả lời của jrb dưới đây?
George

Xem câu trả lời của rpyzh dưới đây. Hiển thị tải tệp bằng cách sử dụng mã hóa phù hợp cũng như lưu tệp bằng một mã khác (mặc dù câu trả lời có thể cần thêm một số giải thích). Ghi chú cuối cùng của Jrb là đủ nếu bạn chỉ muốn đọc nó, nhưng không phải nếu bạn muốn lưu nó mà không có byte rỗng bằng cách sử dụng mã hóa khác.
Mario

50

Tôi không nghĩ rằng các tập tin của bạn bị hỏng. Dòng ví dụ của bạn trông giống như nó chứa văn bản thông thường với các byte rỗng giữa mỗi ký tự. Điều này cho thấy đây là một tệp văn bản được mã hóa theo UTF-16 nhưng dấu thứ tự byte bị thiếu từ đầu tệp. Xem http://en.wikipedia.org/wiki/Byte-order_mark

Giả sử tôi mở Notepad, nhập từ 'tên tệp' và lưu dưới dạng Unicode Big-endian. Một kết xuất hex của tệp này trông như thế này:

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

Nếu tôi mở tệp này trong Vim thì có vẻ ổn - các byte 'ff' cho Vim biết cách mã hóa tệp. Bây giờ, giả sử tôi tạo một tệp chứa chính xác chuỗi byte, nhưng không có 'ff' hàng đầu. Vim chèn ^ @ (hoặc <00>, tùy thuộc vào cấu hình của bạn), thay cho các byte rỗng; Notepad chèn khoảng trắng.

Vì vậy, thay vì loại bỏ các null, bạn thực sự nên tìm cách để Vim diễn giải chính xác tệp. Bạn có thể yêu cầu Vim tải lại tệp với mã hóa chính xác bằng lệnh:

:e ++enc=utf16


Có, lệnh cuối cùng khiến vim diễn giải chính xác tệp nhưng không xóa nullbyte.
mrt181

6
Để xóa chúng, chọn mã hóa khác và lưu lại tệp :: set
fenc

35

Điều này thực sự làm việc cho tôi trong vim:

:%s/\%x00//g

5
cái này hoạt động với thay thế (), nhưng Ctl-VCtl-Shift-2 thì không.
DSummersl

Vấn đề tương tự đối với tôi, tôi cũng không thể làm cho <Ctrl-V><Ctrl-2>(cũng như người có <Ctrl-Shift-2>) làm việc, nhưng điều này đã làm việc.
Jeff Bridgman

5
Điều này làm việc cho tôi linux. '00' là giá trị hex ASCII, bạn có thể tìm thấy bất kỳ ký tự nào trong vim bằng cách đặt con trỏ lên trên nó và gõ 'ga' (nghĩ "get ascii) trong chế độ lệnh hoặc: as /: ascii trên dòng lệnh. Vim .wikia.com / wiki / SSH
Casey Jones

^ Vx00 cũng hoạt động. Bạn cũng có thể nhập unicode 16 bit bằng ^ VuXXXX. Tôi đã thử \% uXXXX trong một tìm kiếm và nó cũng hoạt động.
Edward Falk

Bạn sẽ là người đàn ông yêu quý của tôi cho đến cuối thời gian. Từ sâu thẳm trái tim tôi ... cảm ơn bạn!
Gonzalo Cao

12

Đó là 'biểu tượng' đại diện cho một ký tự NULL, với giá trị ASCII 000.

Rất khó để xóa bằng vim, hãy thử

tr -d '\000' < file1 > file2

7

Như những người khác đã lưu ý, đó là những byte rỗng (ASCII 00). Trên Linux, cách nhập giá trị ASCII vào vim là nhấn Ctrl-V theo sau là giá trị bát phân 3 chữ số của bất kỳ ký tự nào. Để thay thế tất cả các byte null, sử dụng:

    :%s/Ctrl-V000//g

(không có khoảng trắng).

Tương tự như vậy, bạn có thể tìm kiếm null với:

    /Ctrl-V000

Trong cả hai trường hợp, nó sẽ không hiển thị các số không khi bạn nhập chúng, nhưng sau khi nhập cả ba, nó sẽ hiển thị ^@. Trên các thiết bị đầu cuối màu, nó sẽ hiển thị màu xanh lam để biểu thị rằng đó là ký tự điều khiển.


6

FWIW, trong trường hợp của tôi, tôi đã phải sử dụng vim trên cygwin để chỉnh sửa tệp văn bản được tạo trên máy mac. Các giải pháp được chấp nhận không làm việc cho tôi, nhưng đã gần. Theo trang wiki Vim về làm việc với Unicode , có một sự khác biệt giữa các phiên bản Big Endian và Little Endian của byte BOM. Vì vậy, tôi đã phải nói rõ ràng vimđể sử dụng phiên bản mã hóa BOM của Little Endian.

Chỉ sau khi chọn mã hóa đúng, tôi mới chuyển đổi định dạng tệp (kết thúc dòng) thành dosđể tôi có thể chỉnh sửa tệp trong trình chỉnh sửa Windows. Cố gắng đặt lại định dạng tệp trước khi chỉ định mã hóa khiến tôi đau buồn. Dưới đây là danh sách đầy đủ các lệnh tôi đã sử dụng:

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

Thông tin quý giá. Trong trường hợp của tôi, đó là tuổi thọ của byte BOM.
Andre Albuquerque

3

Các giải pháp được chấp nhận đã không làm việc cho tôi. Tôi đã thực hiện vim ống các tập tin thông qua trthay thế:

:%!tr -d '\000'

Điều này cũng sẽ hoạt động tốt với chế độ trực quan (chỉ cần gõ :!tr -d '\000') hoặc trên một loạt các dòng:

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

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

2

^@ không phải là một ký tự xấu nếu bạn sử dụng một mã hóa phù hợp, nhưng nếu bạn muốn loại bỏ thì hãy thử:

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

^ Ký tự M có trong dữ liệu mẫu của bạn

Để chuyển đổi tệp của bạn sang định dạng Unix / Linux trước khi xử lý, hãy thử:

dos2unix filename - rrc và khác

dos2ux filename [newfilename] - HP-UX


1

Ngoài câu trả lời của @ jrb, trong Vim, mã hóa ký tự của tệp được phát hiện dựa trên tùy chọn tệp khởi tạo. (lưu ý 's' ở cuối tập tin)

Tức là trên Windows, giá trị mặc định cho fileencodingstùy chọn là ucs-bom, có nghĩa là:

kiểm tra nếu BOM tồn tại ở đầu tập tin.

Nếu BOM tồn tại, thì 'đọc mã hóa ký tự của tệp ra khỏi BOM'.

Nếu BOM không tồn tại (và trong trường hợp này cũng có nghĩa là tất cả các mã hóa ký tự được chỉ định trong fileencodingstùy chọn không khớp), thì hãy đọc tệp có mã hóa ký tự được chỉ định trong encodingtùy chọn. Mã hóa ký tự mặc định cho encodingtùy chọn là : latin1. Bây giờ, vì latin1là mã hóa ký tự có độ dài một byte , tất cả các byte trong tệp là các latin1ký tự hợp lệ (ngay cả Nulký tự ^@mà bạn đang nhìn thấy *).

* - thực ra, ^@là ký tự dòng mới trong văn bản bộ đệm của Vim, không phải ký tự Nul.

Cách thích hợp để đọc tệp là chỉ định mã hóa ký tự theo cách thủ công là UTF-16 (vì có vẻ như UTF-16 là mã hóa char thích hợp trong trường hợp này).

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.