Мне нужно найти и заменить все вхождения неизвестного символа в некоторых файлах с одинаковыми именами.
Открывая такие файлы с помощью vi, я прочитал код <91> для этого символа. Открыв их с помощью nano, я прочитал «вопросительный знак» в ромбе (черный грохот).
Я хотел бы заменить такой неизвестный символ кавычкой ('). Я пытаюсь много способов без удачи.
Я старался:
find ./ -name filename.txt -exec perl -i~ -pe "s/\x91/'/" {} \;
find ./ -name filename.txt -exec sed -i "s/\x91/'/g" {} \;
РЕДАКТИРОВАТЬ Подробнее о персонаже:
Hexadecimal: 91 68 74 74
Decimal: 145 104 116 116
Octal: 221 150 164 164
Binary: 10010001 01101000 01110100 01110100
LC_ALL=C sed -n l < file
\221
Если вам нужно больше, спросите!
sed -i "s/\x91/'/g"
на этомfile
не работает?Ответы:
Вы должны посмотреть используя
hexdump -C
и найти байты вокруг него. Предполагая UTF-8, то, чтоvi
отображается как<91>
(десятичное число 145, точка Unicode не имеет смысла в тексте), будет два байта, 0xc2 и 0x91.Это подразумевает, что ваши замены вообще не работали, но если вы просто заменили 0x91 на 0x27, вы лишите законной силы UTF-8 (у второго байта двухбайтовой последовательности всегда установлен старший бит, т.е. > = 0x80). Это может усложнить ваш анализ, хотя
vi
затем следует показать его как?'
.Тем не менее, я проверил это, и это работает:
Если
$ARGV[0]
существует, когда на<>
него ссылаются, Perl извлекает это из стека аргументов и принимает его как путь к файлу, чтобы использовать для ввода (я считаю, что короткие сценарии легче настраивать и работать с ними, чем с одним вкладышем, кстати). Это накапливается в памяти (хорошо, пока файлы не массивны), тогдаperl -i
как исходный файл переименовывается, чтобы избежать условий гонки по месту (см.perldoc perlrun
).Таким образом, вы можете использовать это:
источник
hexdump -C
чтобы увидеть, что на самом деле там?Если это действительно символ U + 0091 (0xc2 0x91 в кодировке UTF-8), а не байт 0x91, то:
Преобразует это в
'
.С GNU
sed
:Редактировать:
Однако, в вашем случае, файл не в UTF-8. Символы UTF-8 - один байт, только для символов ASCII (для значений от 0 до 0x7F). Другие символы представлены двумя или более байтами, значение которых больше, чем
0x7F
. Таким образом,0x91
байт без байта больше 0x7F не может быть найден в файле utf-8.Скорее всего, ваш файл находится в однобайтовом наборе символов, скорее всего, в Microsoft, например windows-1252 .
В windows-1252 0x91 - это символ левой кавычки. Эквивалентом в Юникоде является U + 2018, который записан в UTF-8
0xe2 0x80 0x98
.Если вы хотите преобразовать свой файл в UTF-8, лучше всего использовать специальный инструмент для этого. Подобно:
Или:
Или, если вы хотите сделать это для каждого
filename.txt
:источник
U+0091
. Пожалуйста, добавьте выводLC_ALL=C sed -n l < file
к вопросу.