Isso não está funcionando porque iconv
primeiro cria o arquivo de saída (já que o arquivo já existe, ele o trunca) e depois começa a ler o arquivo de entrada (que agora está vazio). A maioria dos programas se comporta dessa maneira.
Crie um novo arquivo temporário para a saída e mova-o para o lugar.
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Se a sua plataforma iconv
não tiver -o
, você poderá usar um redirecionamento de shell para o mesmo efeito.
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
O sponge
utilitário de Colin Watson (incluído no moreutils de Joey Hess ) automatiza isso:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Esta resposta se aplica não apenas a, iconv
mas a qualquer programa de filtro. Vale a pena mencionar alguns casos especiais:
- O GNU sed e o Perl
-p
têm uma -i
opção para substituir os arquivos no local.
- Se o arquivo for muito grande, o filtro só é alterar ou remover algumas partes, mas nunca adicionando coisas (por exemplo
grep
, tr
, sed 's/long input text/shorter text/'
), e você gosta de viver perigosamente, você pode querer realmente modificar o arquivo no local (as outras soluções mencionadas aqui criar uma novo arquivo de saída e mova-o para o lugar no final, para que os dados originais permaneçam inalterados se o comando for interrompido por qualquer motivo).