Как я могу предотвратить sed -i от уничтожения символических ссылок?


21

Почему sed -iвыполняется по символической ссылке уничтожает эту ссылку и заменяет ее с целевым файлом? Как этого избежать?

например.

$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:46 pet
lrwxrwxrwx 1 madneon madneon 6 mar 23 16:48 pet_link -> pet

$ sed -i 's/cat/dog/' pet_link

$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:48 pet
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:49 pet_link

И почему это не считается ошибкой?

Ответы:


25

-i/ --in-placeФлаг редактирует файл на месте. По умолчанию sedчитает указанный файл, обрабатывает его вывод во временный файл, затем копирует временный файл поверх оригинала, не проверяя, был ли оригинал символической ссылкой.

У GNU sedесть --follow-symlinksфлаг, который заставляет его вести себя так, как вы хотите:

$ echo "cat" > pet
$ ln --symbolic pet pet_link
$ sed --in-place --follow-symlinks 's/cat/dog/' pet_link
$ cat pet
dog

6
Он не редактирует файл на месте, но редактирует временную копию файла в текущем каталоге, а затем перемещает эту временную копию поверх оригинала.
mikeserv

@mikeserv Я пропустил детали реализации, потому что вопрос был об интерфейсе. Полезно знать, хотя, спасибо!
Анко

1

Это не ошибка, это дизайн, так sedкак это S- tream ED itor , а не редактор файлов. Он в основном делает копию и заменяет оригинальный файл копией. BashFAQ

В качестве альтернативы вы можете использовать exкоманду, которая имеет аналогичный синтаксис для замены, например

ex +%s/cat/dog/ge -scwq pet_link

или несколько файлов:

ex "+bufdo! %s/cat/dog/ge" -scxa **/pet_link*

Это не разрушит символические ссылки.

Связанный: Как я могу препятствовать тому, чтобы sed разрушил hardinks?


0

Я считаю, что это также хорошо работает (сохраняя как символические, так и жесткие ссылки):

sed 's/cat/dog/' pet_link > pet_link.tmp
cat pet_link.tmp > pet_link
rm pet_link.tmp

0

Существует решение, которое мы иногда используем для записи в тот же файл, из которого выполняется чтение. Вот выдержка из справочной страницы:

   sponge reads standard input and writes it out to the specified file.
   Unlike a shell redirect, sponge soaks up all its input before opening
   the output file. This allows constructing pipelines that read from and
   write to the same file.

   It also creates the output file atomically by renaming a temp file into
   place, and preserves the permissions of the output file if it already
   exists. If the output file is a special file or symlink, the data will
   be written to it.

Вот фрагмент, который показывает, что он может сохранять символические ссылки, хотя я обычно использую его для сохранения inode:

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

rm -f pet pet_link
echo "cat" > pet
pl " Input data file $FILE:"
head -v pet

pl " Results, before sed:"
ln --symbolic pet pet_link
ls -ligG pet pet_link
# sed --in-place --follow-symlinks 's/cat/dog/' pet_link
pe
pe " Results, after sed:"
sed 's/cat/dog/' pet_link | sponge pet_link
head -v pet
ls -ligG pet pet_link

который производит:

-----
 Input data file data1:
==> pet <==
cat

-----
 Results, before sed:
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet

 Results, after sed:
==> pet <==
cat
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet

В такой системе, как:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30

Код губки доступен в пакете moreutils - некоторые подробности:

sponge  soak up standard input and write to a file (man)
Path    : /usr/bin/sponge
Package : moreutils
Home    : http://kitenet.net/~joey/code/moreutils/
Version : 0.52
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)

В нашем магазине мы написали версию, которая записывает во временный файл для случая очень больших файлов.

Пакет доступен на Debian, Fedora, macOS (через brew) и т. Д. ... ура,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.