Tengo un script bash que enumera a través de cada archivo * .php en un directorio y se aplica iconv
a él. Esto obtiene salida en STDOUT.
Dado que agregar el -o
parámetro (en mi experiencia) en realidad escribe un archivo en blanco probablemente antes de que tenga lugar la conversión, ¿cómo puedo ajustar mi script para que realice la conversión y luego sobrescribe el archivo de entrada?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
shell
text-processing
io-redirection
meder omuraliev
fuente
fuente
Respuestas:
Esto no funciona porque
iconv
primero crea el archivo de salida (dado que el archivo ya existe, lo trunca), luego comienza a leer su archivo de entrada (que ahora está vacío). La mayoría de los programas se comportan de esta manera.Cree un nuevo archivo temporal para la salida, luego muévalo a su lugar.
Si su plataforma
iconv
no tiene-o
, puede usar una redirección de shell para el mismo efecto.La
sponge
utilidad de Colin Watson (incluida en moreutils de Joey Hess ) automatiza esto:Esta respuesta se aplica no solo
iconv
a cualquier programa de filtro, sino también a él. Vale la pena mencionar algunos casos especiales:-p
tienen una-i
opción para reemplazar archivos en su lugar.grep
,tr
,sed 's/long input text/shorter text/'
), y te gusta vivir peligrosamente, es posible que desee realmente modificar el archivo en su lugar (las otras soluciones mencionadas aquí crean una nuevo archivo de salida y muévalo a su lugar al final, de modo que los datos originales no cambien si el comando se interrumpe por cualquier motivo).fuente
sponge
debe atribuirse exclusivamente a Joey Hess; es el paquetemoreutils
que incluye losponge
que mantiene, pero en lo que respecta al origen desponge
, siguiendo los enlaces de la página de inicio demoreutils
, he encontrado originalmente publicado y sugerido para su inclusión por Colin Watson: "Joey escribe sobre la falta de nuevas herramientas que encaja en la filosofía de Unix. Mi favorito de las cosas que he escrito essponge
"(Lun, 06 de febrero de 2006).iconv -f cp1251 -t utf8 "$file" > "$file.new"
sort
, son bastante inteligentes con respecto a los-o
parámetros, y si detectan que el archivo de salida es igual a la entrada, administran internamente un archivo temporal, por lo que simplemente funciona.Una alternativa es
recode
, que utiliza la biblioteca libiconv para algunas conversiones. Su comportamiento es reemplazar el archivo de entrada con la salida, por lo que esto funcionará:Como
recode
acepta múltiples archivos de entrada como parámetro, puede ahorrar elfor
bucle:fuente
info recode
lugar. Es más detallado.Por ahora
Funciona de maravilla
fuente
Puede usar Vim en modo Ex:
%
seleccione todas las líneas!
ejecutar comandox
guardar y cerrarfuente
Aquí hay un ejemplo simple . Debería darle una información suficiente para comenzar.
fuente
funciona para mi
fuente
Puedes usar find, al menos esto funcionó para mí en Raspbian Stretch:
fuente
Una opción es usar
perl
la interfaziconv
y su-i
modo para la edición in situ:Con GNU
awk
, también puedes hacer algo como:El
ksh93
shell también tiene un>;
operador para aquello que almacena la salida en un archivo temporal que se renombra al archivo redirigido si el comando fue exitoso:fuente