Provavelmente, esse arquivo é codificado em UTF-16, ou seja, com 2 ou 4 bytes por caractere, provavelmente até mesmo com uma marca de ordem de bytes no começo.
Os caracteres que são mostrados no seu exemplo (todos os caracteres ASCII) são tipicamente codificados em 2 bytes, sendo o primeiro ou o segundo (dependendo se é uma codificação UTF-16 big-enfian ou little-endian) sendo 0 e o outro é o código ASCII / Unicode. O byte 0 é normalmente invisível em um terminal, de modo que o texto aparece OK quando descartado, pois o resto é apenas ASCII, mas o texto contém:
<[NUL]S[NUL]t[NUL]a[NUL]r[NUL]t[NUL]W[NUL]h[NUL]e[NUL]n[NUL]...
Você precisaria converter esse texto para o conjunto de caracteres do seu local para que sed
fosse capaz de lidar com ele. Note que o UTF-16 não pode ser usado como uma codificação de caracteres em uma localidade no Unix. Você não encontrará uma localidade que use o UTF-16 como codificação de caracteres.
iconv -f utf-16 < Task_01.xml |
sed 's~<StartWhenAvailable>true</StartWhenAvailable>~<StartWhenAvailable>false</StartWhenAvailable>~g' |
iconv -t utf-16 > Task_01.xml.out
Isso pressupõe que a entrada tenha uma lista de materiais. Se não, você precisa determinar se é big endian ou little endian (provavelmente little endian) e altere esse utf-16
para utf-16le
ou utf-16be
.
Se o conjunto de caracteres do locale for UTF-8, não deverá haver nada perdido na tradução, mesmo que o texto contenha caracteres não-ASCII.
Como o sed
do Cygwin é tipicamente GNU sed
, ele também será capaz de lidar com esse tipo de entrada binária (já que contém bytes NUL) por si só, então você também pode fazer algo como:
LC_ALL=C sed -i 's/t\x00r\x00u\x00e/f\x00a\x00l\x00s\x00e/g' Task_01.xml
O comando file
deve ser capaz de dizer se a entrada é de fato UTF-16. Você pode usar sed -n l
ou od -tc
para ver esses caracteres NUL ocultos. Exemplo de texto UTF-16 little-endian com BOM:
$ echo true | iconv -t utf-16 | od -tc
0000000 377 376 t set -o pipefail
for file in ./*.xml; do
cp -ai "$file" "$file.bak" &&
iconv -f utf-16 < "$file.bak" |
sed 's~<StartWhenAvailable>true</StartWhenAvailable>~<StartWhenAvailable>false</StartWhenAvailable>~g' |
iconv -t utf-16 > "$file" &&
rm -f "$file.bak"
done
r <[NUL]S[NUL]t[NUL]a[NUL]r[NUL]t[NUL]W[NUL]h[NUL]e[NUL]n[NUL]...
u iconv -f utf-16 < Task_01.xml |
sed 's~<StartWhenAvailable>true</StartWhenAvailable>~<StartWhenAvailable>false</StartWhenAvailable>~g' |
iconv -t utf-16 > Task_01.xml.out
e LC_ALL=C sed -i 's/t\x00r\x00u\x00e/f\x00a\x00l\x00s\x00e/g' Task_01.xml
\n $ echo true | iconv -t utf-16 | od -tc
0000000 377 376 t set -o pipefail
for file in ./*.xml; do
cp -ai "$file" "$file.bak" &&
iconv -f utf-16 < "$file.bak" |
sed 's~<StartWhenAvailable>true</StartWhenAvailable>~<StartWhenAvailable>false</StartWhenAvailable>~g' |
iconv -t utf-16 > "$file" &&
rm -f "$file.bak"
done
r %pre% u %pre% e %pre% \n %pre%
0000014
$ echo true | iconv -t utf-16 | sed -n l
76t%pre%0r%pre%0u%pre%0e%pre%0$
%pre%0$
$ echo true | iconv -t utf-16 | file -
/dev/stdin: Little-endian UTF-16 Unicode text, with no line terminators
0000014
$ echo true | iconv -t utf-16 | sed -n l
76t%pre%0r%pre%0u%pre%0e%pre%0$
%pre%0$
$ echo true | iconv -t utf-16 | file -
/dev/stdin: Little-endian UTF-16 Unicode text, with no line terminators
Para processar vários arquivos com zsh
/ bash
/ ksh93
: