Preciso pesquisar e substituir todas as ocorrências de um caractere desconhecido em alguns arquivos com o mesmo nome.
Abrindo esses arquivos com o vi, li o código <91> para esse caractere. Abrindo-os com nano, eu li um "ponto de interrogação" em um diamante (retângulo preto).
Gostaria de substituir esse caractere desconhecido por uma citação ('). Estou tentando de várias maneiras, sem sorte.
Eu tentei:
find ./ -name filename.txt -exec perl -i~ -pe "s/\x91/'/" {} \;
find ./ -name filename.txt -exec sed -i "s/\x91/'/g" {} \;
EDIT Mais informações sobre o personagem:
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
Se precisar de mais, pergunte!
sed -i "s/\x91/'/g"
issofile
não funciona?Respostas:
Você deve dar uma olhada usando
hexdump -C
e encontrar os bytes ao seu redor. Presumindo UTF-8, o quevi
aparece como<91>
(decimal 145, um ponto unicode sem sentido no texto) seria de dois bytes, 0xc2 e 0x91.Está implícito que suas substituições não funcionaram, mas se o que você fez foi substituir 0x91 por 0x27, você invalidou o UTF-8 (o segundo byte de uma sequência de dois bytes sempre tem o bit alto definido, ou seja, > = 0x80). Isso pode complicar sua análise, embora
vi
deva mostrar como?'
.Dito isto, testei isso e funciona:
Se
$ARGV[0]
existe quando<>
é referenciado, o perl retira isso da pilha de argumentos e o usa como caminho de arquivo a ser usado para entrada (acho que scripts curtos são mais fáceis de ajustar e trabalhar com mais de um liner, BTW). Isso se acumula na memória (ótimo, desde que os arquivos não sejam enormes), enquantoperl -i
renomeia o arquivo original para evitar condições de corrida de edição no local (consulteperldoc perlrun
).Então você pode usar isso:
fonte
hexdump -C
para ver o que realmente está lá?Se for realmente o caractere U + 0091 (0xc2 0x91 na codificação UTF-8) e não o byte 0x91, então:
Conversaria para
'
.Com o GNU
sed
:Editar:
No entanto, no seu caso, o arquivo não está no UTF-8. Os caracteres UTF-8 são de um byte, apenas para caracteres ASCII (para valores de 0 a 0x7F). Os outros caracteres são representados por dois ou mais bytes cujo valor é maior que
0x7F
. Portanto, um0x91
byte, sem byte maior que 0x7F, não pode ser encontrado em um arquivo utf-8.O mais provável é que o arquivo esteja em um conjunto de caracteres de byte único, provavelmente em algum da Microsoft como o windows-1252 .
No windows-1252, 0x91 é o caractere de aspas simples à esquerda. O equivalente unicode é U + 2018, que está escrito em UTF-8
0xe2 0x80 0x98
.Se você deseja converter seu arquivo em UTF-8, o melhor é provavelmente usar uma ferramenta dedicada para isso. Gostar:
Ou:
Ou se você quiser fazer isso para todos
filename.txt
:fonte
U+0091
. Por favor, adicione a saída deLC_ALL=C sed -n l < file
para a pergunta.