[unix] 제자리에 sed 편집 파일

편집 된 내용을 새 파일로 수동으로 스트리밍 한 다음 새 파일의 이름을 원래 파일 이름으로 바꾸지 않고 단일 sed 명령 으로 파일을 편집 할 수 있는지 확인하려고합니다 . -i옵션을 사용해 보았지만 Solaris 시스템 -i이 잘못된 옵션 이라고 말했습니다 . 다른 방법이 있습니까?



답변

-i옵션 은 편집 된 컨텐츠를 새 파일로 스트리밍 한 다음 장면 뒤에서 이름을 바꿉니다.

예:

sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename

sed -i '' 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename

맥 OS .


답변

sed적절한 위치에 파일을 편집 할 수없는 시스템에서는 더 나은 솔루션을 사용하는 것이 좋습니다 perl.

perl -pi -e 's/foo/bar/g' file.txt

임시 파일을 만들지 만 비어있는 적절한 접미사 / 확장자가 제공 되었기 때문에 원본 파일을 대체합니다.


답변

OS X에서는이 명령을 실행할 때 “유효하지 않은 명령 코드”와 같은 이상한 오류나 다른 이상한 오류가 발생할 수 있습니다. 이 문제를 해결하려면

sed -i '' -e "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>

의 OSX 버전 때문이다 sed-i옵션은 예상 extension명령이 실제로로서 해석되도록 인수 extension인수 및 파일 경로가 명령 코드로 해석됩니다. 출처 : https://stackoverflow.com/a/19457213


답변

다음은 내 Mac에서 잘 작동합니다.

sed -i.bak 's/foo/bar/g' sample

샘플 파일에서 foo를 bar로 바꿉니다. 원본 파일의 백업은 sample.bak에 저장됩니다

백업없이 인라인을 편집하려면 다음 명령을 사용하십시오.

sed -i'' 's/foo/bar/g' sample


답변

주목해야 sed할 것은 sed의 유일한 목적으로 파일을 자체적으로 작성할 수 없다는 것입니다. “스트림”의 편집기 (예 : stdin, stdout, stderr 및 기타 >&n버퍼, 소켓 등의 파이프 라인 )로 작동하는 것입니다. 이를 염두에두고 다른 명령 tee을 사용 하여 출력을 파일에 다시 쓸 수 있습니다 . 또 다른 옵션은 컨텐츠를로 파이핑하여 패치를 작성하는 것 diff입니다.

티 방법

sed '/regex/' <file> | tee <file>

패치 방법

sed '/regex/' <file> | diff -p <file> /dev/stdin | patch

최신 정보:

또한 patch는 diff 출력의 1 행에서 파일을 변경합니다.

패치는 diff의 출력 첫 줄에있는 파일 중 액세스 할 파일을 알 필요가 없습니다.

$ echo foobar | tee fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin
*** fubar   2014-03-15 18:06:09.000000000 -0500
--- /dev/stdin  2014-03-15 18:06:41.000000000 -0500
***************
*** 1 ****
! foobar
--- 1 ----
! fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin | patch
patching file fubar


답변

당신이 원하는 것을 할 수는 없습니다 sed. sed해당 버전의 -i파일을 수정하는 옵션을 지원하는 버전조차도 사용자가 명시 적으로 원하지 않는 것을 정확하게 수행합니다. 임시 파일에 쓴 다음 파일 이름을 바꿉니다. 그러나 아마도 당신은 그냥 사용할 수 있습니다 ed. 예를 들어, 모든 항목 변경 foobar파일의를 file.txt, 당신은 할 수 있습니다 :

echo ',s/foo/bar/g; w' | tr \; '\012' | ed -s file.txt

구문은와 유사 sed하지만 정확히 동일하지는 않습니다.

그러나 이름이 바뀐 임시 파일을 사용하지 않는 이유를 고려해야합니다. 당신이없는 경우에도 -i지원을 sed, 당신은 쉽게 당신을 위해 일을하는 스크립트를 작성할 수 있습니다. 대신 sed -i 's/foo/bar/g' file할 수 있습니다 inline file sed 's/foo/bar/g'. 이러한 스크립트는 작성하기가 쉽지 않습니다. 예를 들면 다음과 같습니다.

#!/bin/sh -e
IN=$1
shift
trap 'rm -f $tmp' 0
tmp=$( mktemp )
<$IN "$@" >$tmp && cat $tmp > $IN  # preserve hard links

대부분의 용도에 적합해야합니다.


답변

vi를 사용할 수 있습니다

vi -c '%s/foo/bar/g' my.txt -c 'wq'