sed -i가 심볼릭 링크를 파괴하지 못하게하려면 어떻게합니까?


21

sed -isymlink에서 실행하면 해당 링크가 삭제되고 대상 파일로 대체되는 이유는 무엇 입니까? 이것을 피하는 방법?

예.

$ 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 인터페이스에 관한 질문 때문에 구현 세부 사항을 건너 뛰었습니다. 그래도 감사합니다!
Anko

1

이 때문에이 디자인입니다, 버그가 아니라 sedA는 S tream ED 당사 홈페이지가 아닌 파일 편집기. 기본적으로 복사본을 만들고 원본 파일을 복사본으로 바꿉니다. BashFAQ

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

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

또는 여러 파일 :

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

심볼릭 링크를 파괴하지 않습니다.

관련 : 내가 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 ...)

우리 가게에서는 매우 큰 파일의 경우 임시 파일에 쓰는 버전을 작성했습니다.

패키지는 데비안, 페도라, macOS (양조를 통해) 등에서 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.