Me gustaría reemplazar un conjunto de caracteres con los caracteres correspondientes de otro conjunto, algo como esto:
original set: ots
"target" set: u.x
foobartest → fuubar.ex.
Traducciones / transliteraciones como esta son la especialidad del trcomando:
$ echo 'foobartest' | tr 'ots' 'u.x'
fuubar.ex.
Lamentablemente trno admite el cambio de archivos en el lugar como lo sedhace.
Me gustaría usar sedpara no tener que reinventar la rueda de malabares con los archivos temporales.

tr(correctamente) ignora la recursividad en los conjuntos de reemplazo:echo 'abc' | tr ab bx→bxc. Una solución primitiva podría hacerloxxcporque vuelve a aplicar la traducción a los caracteres que ya se han traducido.sedcontrario a GNUtrpuede transliterar caracteres de varios bytes)Respuestas:
sedtiene elycomando que funciona igual quetr:El
ycomando es parte de la especificación POSIXsed, por lo que debería funcionar en casi cualquier plataforma.Y dado que es así
sed, puede hacer que reemplace un archivo con su versión editada, ahorrándole el molesto negocio de los archivos temporales (siempre que su implementación de seasedcompatible con la-iopción, que no está especificada por POSIX):fuente
sedla de s no significa que las otras funciones también lo estén. ;) La lista de correo de Vim tiene un hilo sobre encontrar uny/abc/def/equivalente; La mejor opción parece ser:%call setline(".", tr(getline("."),"abc","def")).Si, como en su caso, está transcribiendo caracteres sin cambiar su tamaño (de todos modos, algunas implementaciones como GNU
trsolo admiten caracteres de un solo byte), puede hacer:Es decir,
trsobrescribir el archivo sobre sí mismo.Eso es mejor que
sed -ien varias cuentas:Un inconveniente es que si se interrumpe, el archivo terminará siendo medio traducido (en este caso, sin embargo, puede ejecutarlo nuevamente para finalizarlo). Algunas
sedimplementaciones manejarían eso correctamente asegurándose de que el archivo original permanezca sin cambios a menos que el comando tenga éxito.fuente
echo 'abc' | tr ab bx.try en nuestro entorno PXE con muchos enlaces simbólicos,sed -iera una espera de mierda sucederá ...: /iconv -t cp437parece más apropiado para eso.iconvse rompe cuando el archivo de entrada ya contiene bytes codificados con cp437, o una mezcla de codificaciones múltiples. Entonces, aunque es preferible en el caso general, es más robusto hacer reemplazos manuales en este caso.Como otra alternativa, si su problema principal es la falta de soporte para cambiar los archivos en el lugar, es posible que le interese la
spongeherramienta del paquete moreutils :escribirá en
file, pero solo se abriráfilepara escribir una vez que se complete la entrada. Desde la página del manual :A menos que tenga archivos realmente grandes que no se pueden guardar en la memoria,
spongepodría funcionar para usted.fuente
spongees que todavía se sobrescribefilesitrfalla (por ejemplo, si tenía acceso de escritura pero no de lecturafile)cat file >; fileoperador de ksh93 que escribe la salida en un archivo temporal que se renombra al destino solo si el comando tiene éxito (perosed -i, como , eso crea un nuevo archivo en lugar de sobrescribir el original).