Использование 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
будет читать весь файл.
Существует небольшая вероятность того, что ваш исходный файл будет потерян, если ваш shell / script / sed будет убит до того, как это будет сделано.
/usr/gnu/bin/sed
для получения поддержки -i.