Это не работает, потому что iconv
сначала создается выходной файл (поскольку файл уже существует, он усекает его), а затем начинает читать его входной файл (который теперь пуст). Большинство программ ведут себя так.
Создайте новый временный файл для вывода, затем переместите его на место.
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Если ваша платформа iconv
не имеет -o
, вы можете использовать перенаправление оболочки для того же эффекта.
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
sponge
Утилита Колина Уотсона (включена в moreutils Джои Хесса ) автоматизирует это:
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Этот ответ относится не только iconv
к любой программе фильтрации. Стоит упомянуть несколько особых случаев:
- GNU sed и Perl
-p
имеют -i
возможность заменить файлы на месте.
- Если файл очень большой, ваш фильтр не только изменение или удаление некоторых частей , но никогда не добавлять вещи (например
grep
, tr
, sed 's/long input text/shorter text/'
), и вам нравится жить опасно, вы можете действительно изменить файл в месте (другие решения , упомянутые здесь , создают новый выходной файл и переместите его на место в конце, чтобы исходные данные не изменялись, если по какой-либо причине команда была прервана).