Использование того же файла, что и для stdin и stdout, приводит к пустому файлу
Если хотите отфильтровать файл, но если я использую тот же файл, что и для ввода и вывода, выходной файл будет пустым. Есть ли другое решение вместо использования второго файла?
php -r "echo preg_replace('~/\* DEV \*/(.*)/\* ENDDEV \*/~si', '', file_get_contents('php://stdin'));" < build/index.php > build/index.php
1 ответ
Когда вы открываете файл для записи с >
, оно обрезается еще до того, как вы его прочитаете. Вот почему он пуст.
Альтернатива с временным файлом (да, это довольно часто):
php -r "…" < build/index.php > tmp
mv tmp build/index.php
В идеале использовать mktemp
создать уникальный временный файл:
tmp="$(mktemp /tmp/file.XXX)"
php -r "…" < build/index.php > "$tmp"
mv "$tmp" build/index.php
Но это на самом деле не короче и не лаконичнее.
Мой личный фаворит sponge
Утилита от moreutils - она читает ввод и затем записывает в файл:
php -r "…" < build/index.php | sponge build/index.php
Или, что еще лучше, не делайте подстановку в PHP, а используйте инструмент, который поддерживает редактирование на месте, например, Perl с:
perl -pi -e '…' build/index.php
Похоже на sed
здесь флаг на месте для GNU sed
:
sed -i -e '…' build/index.php
И для BSD sed
вам нужен явный пустой аргумент для -i
:
sed -i '' -e '…' build/index.php
Возможно, вам придется адаптировать вашу команду регулярного выражения / подстановки для синтаксиса Perl и sed соответственно.