¿Existe una alternativa a sed que admita unicode?

33

Por ejemplo:

sed 's/\u0091//g' file1

En este momento, tengo que hacer hexdumppara obtener el número hexadecimal y ponerlo de la sedsiguiente manera:

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

Y entonces:

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

Respuestas:

28

Solo usa esa sintaxis:

sed 's/馑//g' file1

O en la forma escapada:

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

(Tenga en cuenta que las versiones anteriores de Bash y algunos shells no entienden echo -e '\u9991', así que verifique primero).

caos
fuente
1
¿Cuenta sed 馑 como un carácter o 3? Es decir, ¿ echo 馑 | sed s/...//imprime algo?
user253751
@immibis Dado que sedtiene el modificador g, reemplaza todas las ocurrencias también cuando se siguen. También sed debe contarlo como un personaje, ver: echo -ne "馑" | wc -mda 1. Si cuenta los bytes ( wc -c), volvería 3. ¿Entendí tu pregunta correctamente?
caos
Quise decir: ¿ .significa "un carácter" o "un byte"?
user253751
@immibis I coincide con un personaje, por lo tanto, echo 馑 | sed s/...//me da (nada se reemplaza)
caos
44
@chaos: funciona debajo en_US.UTF-8, pero no debajo C.
choroba
15

Perl puede hacer eso:

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

-CS enciende UTF-8 para entrada, salida y error estándar.

choroba
fuente
77
Perl puede hacer casi cualquier cosa .....
wobbily_col
6

Una serie de versiones de sedsoporte Unicode :

  • Reliquia sed , que se basa en el "material original de Unix".
  • GNU sed , que es su propia base de código.
  • Plan 9 sed , que se ha portado a sistemas operativos tipo Unix.

No pude encontrar información sobre BSD sed, lo que me pareció extraño, pero creo que hay muchas posibilidades de que también sea compatible con Unicode. Desafortunadamente, no hay una forma estándar de saber sedqué codificación usar, por lo que cada uno lo hace a su manera.

El más cuchara
fuente
¿Soportan UTF-16 con y sin BOM?
Bon Ami
10
UTF-16 es bastante inutilizable en sistemas operativos basados ​​en Unix. También es una abominación que nunca debería haber visto la luz del día.
Brian Bi
El hecho de que admitan o no UTF-16 depende de la implementación, y me temo que no tengo esos datos. Dudo que el Plan 9 sed lo haga (el sistema operativo original es UTF-8 en todas partes), pero no puedo estar seguro, e incluso si no lo hace, los otros podrían.
The Spooniest
2

Esto funciona para mi:

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

Es una gota más detallada de lo que me gustaría; Aquí hay una explicación completa:

  • -n deshabilitar el archivo de intercambio vim
  • -E Ex modo mejorado
  • -s Modo silencioso
  • +'%s/\%u9991//g' ejecutar el comando de sustitución
  • +wq guardar y Salir
Aryeh Leib Taurog
fuente
Supongo que esto se modifica file1 en el lugar , ¿es correcto?
Gerrit
@gerrit es correcto, y gracias por señalarlo.
Aryeh Leib Taurog
1

Con versiones recientes de BASH, solo omita las comillas alrededor de la expresión sed y puede usar las cadenas escapadas de BASH. Los espacios dentro de la expresión sed o partes de la expresión sed que BASH podría interpretar como comodines se pueden citar individualmente.

$ echo "饥馑荐臻" | sed s/$'\u9991'//g
饥荐臻
Dave Rove
fuente
¡Esta debería ser la nueva respuesta aceptada, simple y limpia!
Allen Wang
0

Funciona para mí con GNU sed (versión 4.2.1):

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

(Como otro reemplazo para sedusted también podría usar GNU awk; pero no parece necesario).

Janis
fuente