Existe-t-il une alternative à sed prenant en charge l’unicode?

33

Par exemple:

sed 's/\u0091//g' file1

En ce moment, je dois faire hexdumppour obtenir le numéro hexadécimal et le mettre sedcomme suit:

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

Et alors:

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

Réponses:

28

Il suffit d'utiliser cette syntaxe:

sed 's/馑//g' file1

Ou sous la forme échappée:

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

(Notez que les anciennes versions de Bash et de certains shells ne comprennent pas echo -e '\u9991', alors commencez par vérifier.)

le chaos
la source
1
Sed compte-t-il 馑 comme un caractère ou 3? C'est-à-dire, echo 馑 | sed s/...//n'imprime rien?
user253751
@immibis Depuis sedle modificateur g, il remplace toutes les occurrences également lorsqu'elles se succèdent. Aussi, sed devrait le compter comme un caractère, voir: echo -ne "馑" | wc -mdonne 1. Si vous comptez le nombre d'octets ( wc -c), il retournera 3. Ai-je bien compris votre question?
chaos
Je voulais dire: .signifie "un caractère" ou "un octet"?
user253751
@immibis I correspond à un personnage echo 馑 | sed s/...//me donne donc (rien n'est remplacé)
chaos
4
@chaos: Cela fonctionne sous en_US.UTF-8, mais pas sous C.
Choroba
15

Perl peut le faire:

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

-CS active UTF-8 pour les entrées, sorties et erreurs standard.

choroba
la source
7
Perl peut faire presque n'importe quoi .....
wobbily_col
6

Un certain nombre de versions du sedsupport Unicode :

  • Heirloom sed , basé sur un "matériel Unix original".
  • GNU sed , qui est son propre code.
  • Plan 9 sed , qui a été porté sur des systèmes d'exploitation de type Unix.

Je ne pouvais pas trouver d'informations sur BSD sed, ce qui me paraissait étrange, mais je pense que les chances sont bonnes qu'il prenne également en charge Unicode. Malheureusement, il n'existe pas de méthode standard permettant de déterminer le sedcodage à utiliser. Chacun le fait à sa manière.

Le Spooniest
la source
Soutiennent-ils UTF-16 avec et sans nomenclature?
Bon Ami
10
UTF-16 est plutôt inutilisable dans les systèmes d'exploitation Unix. C'est aussi une abomination qui n'aurait jamais dû voir le jour.
Brian Bi
Qu'ils supportent ou non UTF-16 dépend de la mise en œuvre, et je crains de ne pas avoir ces données. Je doute que Plan 9 sed le fasse (le système d’exploitation original est UTF-8 partout), mais je ne peux pas en être sûr, et même s’il ne le faisait pas, les autres pourraient le faire.
Le Spooniest
2

Cela fonctionne pour moi:

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

C'est une goutte plus verbeuse que je ne l'aimerais; voici une explication complète:

  • -n désactiver le fichier d'échange vim
  • -E Mode amélioré Ex
  • -s mode silencieux
  • +'%s/\%u9991//g' exécuter la commande de substitution
  • +wq sauvegarder et quitter
Aryeh Leib Taurog
la source
Je suppose que cela modifie file1 en place , est-ce correct?
gerrit
@ gerrit c'est correct, et merci de le signaler.
Aryeh Leib Taurog
1

Avec les versions récentes de BASH, omettez simplement les guillemets autour de l'expression sed et vous pouvez utiliser les chaînes échappées de BASH. Les espaces dans l'expression sed ou des parties de l'expression sed qui pourraient être interprétées par BASH comme des caractères génériques peuvent être individuellement cités.

$ echo "饥馑荐臻" | sed s/$'\u9991'//g
饥荐臻
Dave Rove
la source
Cela devrait être la nouvelle réponse acceptée, simple et propre!
Allen Wang
0

Fonctionne pour moi avec GNU sed (version 4.2.1):

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

(Un autre remplaçant pour sedvous pourrait également utiliser GNU awk; mais cela ne semble pas nécessaire.)

Janis
la source