Використання sed
та не видимий тимчасовий файл:
Ви можете уникнути створення окремого видимого "темп-файлу":
exec 3<abc.txt
rm abc.txt
sed 's/foo/fooofoo/' <&3 >abc.txt
exec 3<&-
Пояснення
Unix-подібні системи на самому ділі не видалити вміст файлу з диска , поки це не як непов'язаний в файлової системі, а не відкривати в будь-якому процесі. Таким чином, ви можете зробити, exec 3<
щоб відкрити файл у оболонці для читання у файлі дескриптора 3, rm
файл (який від’єднує його від файлової системи), а потім викликати sed
дескриптор файлу 3, який використовується як його вхід.
Зауважте, що це сильно відрізняється від цього:
# Does not work.
sed 's/foo/fooofoo/' <abc.txt >abc.txt
Різниця полягає в тому, що, виконуючи це в одній команді, оболонка просто відкриває один і той же файл і для читання, і для запису з можливістю усікати файл - оскільки це все-таки той самий файл, ви втрачаєте вміст. Але якщо ви відкриєте його для читання, то rm
це, потім відкрийте те саме ім'я шляху для запису, ви фактично створюєте новий файл з тим же ім'ям шляху (але в новому місці вводу та диска, оскільки оригінал все ще відкритий): так вміст все ще доступний.
Потім, коли ви закінчите, ви можете закрити дескриптор файлів, який ви відкрили раніше (саме це робить exec 3<&-
спеціальний синтаксис), який випускає оригінальний файл, щоб операційна система могла видалити (позначити як невикористаний) свій диск на диску.
Коваджі
Про це рішення слід пам’ятати кілька речей:.
Ви отримуєте лише один "перехід" через вміст - у дескрипторі файлів немає переносного способу, щоб оболонка "шукала" - тому, як тільки програма прочитає частину вмісту, інші програми побачать лише решту файлу. І sed
прочитає весь файл.
Існує невеликий шанс, що ваш оригінальний файл буде загублений, якщо ваша оболонка / скрипт / sed буде вбита, перш ніж це буде зроблено.
/usr/gnu/bin/sed
щоб отримати підтримку -i.