sed -i가 심볼릭 링크를 깨는 것을 방지하는 방법은 무엇입니까?

sed -i가 심볼릭 링크를 깨는 것을 방지하는 방법은 무엇입니까?

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

왜 오류로 간주되지 않습니까?

답변1

-i/flag --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

답변2

이것은 버그가 아니며 의도적으로 설계된 sed것 입니다.에스트레메응급실itor는 파일 편집기가 아닙니다. 기본적으로 복사본을 만들고 원본 파일을 복사본으로 바꿉니다.배쉬 FAQ

ex또는 유사한 대체 구문이 있는 명령을 대신 사용할 수 있습니다 .

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

또는 여러 파일:

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

심볼릭 링크는 깨지지 않습니다.

관련된:sed가 Hardink를 파괴하는 것을 방지하는 방법은 무엇입니까?

답변3

나는 이것이 또한 잘 작동한다는 것을 알았습니다(심볼릭 링크와 하드 링크를 보존함):

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

답변4

때때로 우리는 읽은 것과 동일한 파일에 쓰기 위해 솔루션을 사용합니다. 다음은 매뉴얼 페이지에서 발췌한 내용입니다.

   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

스폰지 코드에는 포장이 있습니다더 많은 유틸리티-- 일부 세부정보:

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를 통해) 등에서 사용할 수 있습니다. 건배,

관련 정보