Tengo un script bash que enumera todos los archivos *.php en un directorio y aplica iconv lo. Esto obtiene salida en STDOUT.
Desde que se agregó el -o El parámetro (en mi experiencia) en realidad escribe un archivo en blanco probablemente antes de que se realice la conversión, ¿cómo puedo ajustar mi secuencia de comandos para que realice la conversión y luego sobrescriba el archivo de entrada?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
Respuesta aceptada:
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 y luego muévalo a su lugar.
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Si el iconv de su plataforma no tiene -o , puede usar una redirección de shell con el mismo efecto.
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
La sponge de Colin Watson La utilidad (incluida en moreutils de Joey Hess) automatiza esto:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Esta respuesta se aplica no solo a iconv pero a cualquier programa de filtro. Vale la pena mencionar algunos casos especiales:
- GNU sed y Perl
-ptener un-iopción para reemplazar archivos en su lugar. - Si su archivo es extremadamente grande, su filtro solo modifica o elimina algunas partes pero nunca agrega cosas (por ejemplo,
grep,tr,sed 's/long input text/shorter text/'), y le gusta vivir peligrosamente, es posible que desee modificar genuinamente el archivo en su lugar (las otras soluciones mencionadas aquí crean un nuevo archivo de salida y lo mueven a su lugar al final, por lo que los datos originales no se modifican si el comando se interrumpe por cualquier motivo).