Muszę wyszukać i zastąpić wszystkie wystąpienia nieznanego znaku w niektórych plikach o tej samej nazwie.
Otwierając takie pliki za pomocą vi, czytam kod <91> dla tego znaku. Otwierając je nano, przeczytałem „znak zapytania” w rombie (czarny romb).
Chciałbym zastąpić taki nieznany znak cytatem ('). Próbuję na wiele sposobów bez powodzenia.
Próbowałem:
find ./ -name filename.txt -exec perl -i~ -pe "s/\x91/'/" {} \;
find ./ -name filename.txt -exec sed -i "s/\x91/'/g" {} \;
EDYCJA Więcej informacji o postaci:
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
Jeśli potrzebujesz więcej, zapytaj!
sed -i "s/\x91/'/g"
na tymfile
nie działać?Odpowiedzi:
Powinieneś spojrzeć za pomocą
hexdump -C
i znaleźć bajty wokół niego. Zakładając, że UTF-8, to, covi
pokazuje jako<91>
(dziesiętnie 145, punkt unicode bez znaczenia w tekście), to dwa bajty 0xc2 i 0x91.Sugeruje to, że twoje podstawienia wcale nie działały, ale jeśli to, co zrobiłeś, to po prostu zastąpiłeś 0x91 wartością 0x27, unieważniłeś UTF-8 (drugi bajt sekwencji dwóch bajtów zawsze ma ustawiony wysoki bit, tj. > = 0x80). Może to skomplikować twoją analizę, chociaż
vi
powinna to pokazać jako?'
.Powiedziałem, przetestowałem to i działa:
Jeśli
$ARGV[0]
istnieje, gdy<>
się do niego odwołuje, perl usuwa go ze stosu argumentów i bierze go jako ścieżkę do pliku wejściowego (uważam, że krótkie skrypty są łatwiejsze do poprawiania i pracy z więcej niż jednym linerem, BTW). Gromadzi się to w pamięci (tak długo, jak pliki nie są ogromne), aperl -i
zmienia nazwę oryginalnego pliku, aby uniknąć warunków wyścigu edycji na miejscu (patrzperldoc perlrun
).Możesz więc użyć tego:
źródło
hexdump -C
co tam jest?Jeśli rzeczywiście jest to znak U + 0091 (0xc2 0x91 w kodowaniu UTF-8), a nie bajt 0x91, to:
Przekształciłbym to w
'
.Z GNU
sed
:Edytować:
Jednak w twoim przypadku plik nie znajduje się w UTF-8. Znaki UTF-8 są jednobajtowe, tylko dla znaków ASCII (dla wartości od 0 do 0x7F). Pozostałe znaki są reprezentowane przez dwa lub więcej bajtów, których wartość jest większa niż
0x7F
. Więc0x91
bajtu bez bajtu większego niż 0x7F nie można znaleźć w pliku utf-8.Bardziej prawdopodobne jest, że plik ma jednobajtowy zestaw znaków, najprawdopodobniej taki Microsoft jak Windows-1252 .
W Windows-1252 0x91 to lewy pojedynczy cudzysłów. Odpowiednikiem Unicode jest U + 2018, który w UTF-8 jest zapisany
0xe2 0x80 0x98
.Jeśli chcesz przekonwertować plik na UTF-8, najlepiej jest użyć do tego dedykowanego narzędzia. Lubić:
Lub:
Lub jeśli chcesz to zrobić dla każdego
filename.txt
:źródło
U+0091
. Dodaj wynikLC_ALL=C sed -n l < file
do pytania.