Китайские иероглифы, а не латинский, записываются в файл

Когда я запускаю sed так и печатаю на консоль, все в порядке:

 sed '/Q/{ s/Q//g r /Users/ericbrotto/Desktop/question.txt }' Commision.txt 

Но когда я делаю это и выводя файл ta:

 sed '/Q/{ s/Q//g r /Users/ericbrotto/Desktop/question.txt }' Commision.txt > newFile 

… моя новая строка (та, которая была правильно заменена в предыдущем выпуске) теперь читается как куча азиатских (я считаю, мандаринских) символов.

Есть идеи?

Это проблема, связанная с проблемой, которую я поставил ранее .

One Solution collect form web for “Китайские иероглифы, а не латинский, записываются в файл”

Ранее я заметил, что если вы берете ASCII-кодированный текст (или, что то же самое, кодированный ASCII-текст UTF-8) и декодируете его как UTF-16, вы часто получаете «китайские символы» (разные в зависимости от того, декодируете ли вы его как UTF- 16BE или UTF-16LE). Исходя из этого, я думаю, вы имеете дело со смешанными кодировками. Я предполагаю, что Commision.txt кодируется как UTF-16BE или UTF-16LE, так что question.txt является простым ASCII (или кодированным ASCII кодировкой UTF-8) и что ваш newFile заканчивается как недопустимая комбинация кодировок от обоих файлы.

Все должно работать лучше, если вы используете одну и ту же кодировку в обоих файлах; вероятно, UTF-8 будет работать лучше всего. Если вы хотите, чтобы конечный вывод находился в какой-либо другой кодировке, вы можете использовать iconv для его преобразования ( iconv -f UTF-8 -t UTF-16BE <newFile >newfile.utf16be.txt ).


Фактически, кодировка UTF-16 символов ASCII совпадает с кодировкой ASCII, но с дополнительными символами NUL, вставленными между каждым символом ASCII вместе с еще одним NUL до или после всей партии (в зависимости от сущности кодировки UTF-16) , Это означает, что текст ASCII, закодированный как UTF-8, или UTF-16, будет выглядеть «нормальным» при прямом просмотре на терминале UTF-8 (т. Е. Ваша «печать на консоль»).

До тех пор, пока содержимое файла будет раздельным, любая среда просмотра, определяющая кодирование (например, редактор), вероятно, правильно определит кодировку (или, по крайней мере, выбрать тот, который достаточно близко, учитывая, что UTF-8 и многие однобайтовые кодировки идентичны в диапазоне ASCII).

Но вы можете объединить файлы вместе. К сожалению, sed недостаточно «умный», чтобы понять, что он имеет дело с файлами, использующими два разных кодировки текста. В конечном итоге вы, по моим предположениям, файл, который в основном кодируется UTF-16 (из Commision.txt ) с кодированным сектором UTF-8 (из question.txt ) посередине (или где бы вы его не Q ). Результат, вероятно, недопустим, если он полностью декодирован как UTF-8, но, возможно, действителен, когда он полностью декодируется как UTF-16 (хотя с некоторым неожиданным содержимым, где находятся данные UTF-8).


Вот пример:

Commision.txt – кодированный ASCII UTF-16BE (с спецификацией).

 % xxd Commision.txt 0000000: feff 0046 0069 0072 0073 0074 0020 006c ...First .l 0000010: 0069 006e 0065 000a 004c 0069 006e 0065 .ine..Line 0000020: 0020 0077 0069 0074 0068 0020 0061 0020 . .with .a. 0000030: 0075 0063 0020 0027 0071 0027 003a 0020 .uc .'.q.'.:. 0000040: 0028 0051 0029 000a 004c 0061 0073 0074 .(.Q.)...Last 0000050: 0020 006c 0069 006e 0065 000a . .line. 

question.txt – ASCII (или кодированный ASCII UTF-8).

 % xxd question.txt 0000000: 5768 6174 2069 7320 7468 6520 6169 722d What is the air- 0000010: 7370 6565 6420 7665 6c6f 6369 7479 206f speed velocity o 0000020: 6620 616e 2075 6e6c 6164 656e 2073 7761 f an unladen swa 0000030: 6c6c 6f77 3f0a llow?. 

Я совмещаю их с sed .

 % sed '/Q/{ s/Q//g r question.txt }' Commision.txt >newFile 

newFile – это беспорядок.

sed удалил Q как один байт ( 51 ) вместо своего двухбайтового представления UTF-16 ( 00 51 ).
Это разрушает двухбайтовое выравнивание остальной части файла, дает целую длину, которая является нечетной, а не четной, и вводит UTF-16 NULL ( 0000 ).

 % xxd newFile 0000000: feff 0046 0069 0072 0073 0074 0020 006c ...First .l 0000010: 0069 006e 0065 000a 004c 0069 006e 0065 .ine..Line 0000020: 0020 0077 0069 0074 0068 0020 0061 0020 . .with .a. 0000030: 0075 0063 0020 0027 0071 0027 003a 0020 .uc .'.q.'.:. 0000040: 0028 0000 2900 0a57 6861 7420 6973 2074 .(..)..What is t 0000050: 6865 2061 6972 2d73 7065 6564 2076 656c he air-speed vel 0000060: 6f63 6974 7920 6f66 2061 6e20 756e 6c61 ocity of an unla 0000070: 6465 6e20 7377 616c 6c6f 773f 0a00 4c00 den swallow?..L. 0000080: 6100 7300 7400 2000 6c00 6900 6e00 6500 ast .line 0000090: 0a . 

Несмотря на беспорядок, он отлично выглядит в моем терминале UTF-8.

 % cat newFile First line Line with a uc 'q': () What is the air-speed velocity of an unladen swallow? Last line 

Когда я загружаю его в Vim, однако, очевидно, что это не так (на самом деле есть NUL после открытой круглой скобки, но его присутствие вызвало усечение этого сообщения). Vim предупреждает «ОШИБКА КОНВЕРСИИ в строке 2».

 First line Line with a uc 'q': (⤀੗桡琠楳⁴桥⁡楲⵳灥敤⁶敬潣楴礠潦⁡渠畮污摥渠獷慬汯眿਀䰀愀猀琀 氀椀渀攀 

Если я удалю вопросительный знак из question.txt (чтобы снова дать четное число байтов) и регенерирует newFile , я получаю последнюю строку «назад» (хотя она застряла до конца второй строки) и избегает преобразования предупреждение от Vim.

 First line Line with a uc 'q': (⤀੗桡琠楳⁴桥⁡楲⵳灥敤⁶敬潣楴礠潦⁡渠畮污摥渠獷慬汯眊Last line 
  • Тестирование файлов, содержащих определенные номера в его именах
  • Сценарий оболочки для ssh на сервер Unix / Linux из MacOS X 10.10
  • wget не останавливается
  • Как переименовать определенные каталоги, если у родителя есть определенное имя?
  • Как скопировать файлы из каталога, удовлетворяющего определенным критериям
  • Почему я получаю сообщение об ошибке «print_unicode: строка 9: printf: отсутствует символ Unicode для Unicode 0187» с этим скриптом
  • Выделение / исключение / расширение в "команде в переменной"
  • Подстановка переменных grep и командной строки
  • BASH- Найти владельца файла
  • Переключить пользователя на root и выполнить выполнение остальной части скрипта
  • Запуск smartctl на всех дисках сервера
  • Linux и Unix - лучшая ОС в мире.