Isso não está funcionando porque iconvprimeiro 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 iconvnã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 spongeutilitá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, iconvmas a qualquer programa de filtro. Vale a pena mencionar alguns casos especiais:
- O GNU sed e o Perl
-ptêm uma -iopçã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).