Existe uma alternativa para sed que suporte unicode?

33

Por exemplo:

sed 's/\u0091//g' file1

Agora, eu tenho que fazer hexdumppara obter o número hexadecimal e colocar da sedseguinte maneira:

$ echo -ne '\u9991' | hexdump -C
00000000  e9 a6 91                                          |...|
00000003

E depois:

$ sed 's/\xe9\xa6\x91//g' file1
A-letubby
fonte

Respostas:

28

Basta usar essa sintaxe:

sed 's/馑//g' file1

Ou na forma de escape:

sed "s/$(echo -ne '\u9991')//g" file1

(Observe que as versões mais antigas do Bash e alguns shells não entendem echo -e '\u9991', portanto verifique primeiro.)

caos
fonte
1
Sed conta 馑 como um caractere ou 3? Ou seja, echo 馑 | sed s/...//imprime alguma coisa?
user253751
@immibis Como sedpossui o modificador g, ele substitui toda a ocorrência também quando eles se seguem. Também sed deve contar como um personagem, veja: echo -ne "馑" | wc -mgive 1. Se você contar os bytes ( wc -c), ele retornará 3. Entendi sua pergunta corretamente?
caos
Eu quis dizer: .significa "um caractere" ou "um byte"?
user253751
@immibis I corresponde a um caractere, portanto, echo 馑 | sed s/...//me dá (nada é substituído)
caos
4
@chaos: Funciona em baixo en_US.UTF-8, mas não em baixo C.
choroba
15

Perl pode fazer isso:

echo 汉典“馑”字的基本解释 | perl -CS -pe 's/\N{U+9991}/Jin/g'

-CS ativa o UTF-8 para entrada, saída e erro padrão.

choroba
fonte
7
Perl pode fazer quase qualquer coisa .....
wobbily_col
6

Várias versões de sedsuporte Unicode :

  • Heirloom sed , baseado no "material original do Unix".
  • GNU sed , que é sua própria base de código.
  • Plan 9 sed , que foi portado para sistemas operacionais semelhantes ao Unix.

Não consegui encontrar informações sobre o BSD sed, o que achei estranho, mas acho boas as chances de ele também suportar o Unicode. Infelizmente, não há uma maneira padrão de dizer sedqual codificação usar, então cada um faz isso de sua própria maneira.

The Spooniest
fonte
Eles suportam UTF-16 com e sem BOM?
Bon Ami
10
O UTF-16 é bastante inutilizável em sistemas operacionais baseados em Unix. É também uma abominação que nunca deveria ter visto a luz do dia.
Brian Bi
Se eles suportam ou não o UTF-16 depende da implementação, e eu tenho medo de não ter esses dados. Duvido que o Plan 9 sed funcione (o sistema operacional original é UTF-8 em todos os lugares), mas não tenho certeza e, mesmo que não, os outros podem.
The Spooniest
2

Isso funciona para mim:

$ vim -nEs +'%s/\%u9991//g' +wq file1

É uma gota mais detalhada do que eu gostaria; Aqui está uma explicação completa:

  • -n desativar arquivo de troca vim
  • -E Ex modo melhorado
  • -s modo silencioso
  • +'%s/\%u9991//g' executar o comando de substituição
  • +wq salvar e sair
Aryeh Leib Taurog
fonte
Suponho que isso se modifique file1 no local , está correto?
gerrit 10/01
@gerrit está correto, e obrigado por apontar.
Aryeh Leib Taurog
1

Nas versões recentes do BASH, apenas omita as aspas em torno da expressão sed e você pode usar as strings de escape do BASH. Os espaços na expressão sed ou partes da expressão sed que possam ser interpretados pelo BASH como curingas podem ser citados individualmente.

$ echo "饥馑荐臻" | sed s/$'\u9991'//g
饥荐臻
Dave Rove
fonte
Essa deve ser a nova resposta aceita, simples e limpa!
Allen Wang
0

Funciona para mim com o GNU sed (versão 4.2.1):

$ echo -ne $'\u9991' | sed 's/\xe9\xa6\x91//g' | hexdump -C
$ echo -ne $'\u9991' | hexdump -C
00000000  e9 a6 91

(Como outro substituto para sedvocê também pode usar o GNU awk; mas não parece necessário.)

Janis
fonte