편집 된 내용을 새 파일로 수동으로 스트리밍 한 다음 새 파일의 이름을 원래 파일 이름으로 바꾸지 않고 단일 sed 명령 으로 파일을 편집 할 수 있는지 확인하려고합니다 . -i
옵션을 사용해 보았지만 Solaris 시스템 -i
이 잘못된 옵션 이라고 말했습니다 . 다른 방법이 있습니까?
편집 된 내용을 새 파일로 수동으로 스트리밍 한 다음 새 파일의 이름을 원래 파일 이름으로 바꾸지 않고 단일 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 -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
sed
적절한 위치에 파일을 편집 할 수없는 시스템에서는 더 나은 솔루션을 사용하는 것이 좋습니다 perl
.
perl -pi -e 's/foo/bar/g' file.txt
임시 파일을 만들지 만 비어있는 적절한 접미사 / 확장자가 제공 되었기 때문에 원본 파일을 대체합니다.
sudo
. 내 생각에 문제는 최신 GNU 또는 BSD를 설치하지 않고 임시 파일을 수동으로 만들고 이름을 바꾸지 않는 방법에 관한 것 sed
입니다. Perl을 사용하십시오.
sed 's/foo/bar/g' file.txt > file.tmp && mv file.tmp file.txt
. 전체 편집이 임시 파일을 사용하여 이름을 변경한다고 해서 옵션을 사용할 수 없을 때 수동으로 이름을 변경 해야 한다는 의미 는 아닙니다. 원하는 것을 수행 할 수있는 다른 도구가 있으며 Perl이 확실한 선택입니다. 이것이 원래 질문에 대한 답이 아닌가?
sed
. 이 질문은 실제로 매우 좋은 것이었지만, 맨 페이지를 읽지 못하거나 여기에 실제로 질문을 읽을 필요가없는 사람들에 의해 그 가치는 줄어 들었 습니다.
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
brew install gnu-sed
와 함께 PATH
sed의 GNU 버전을 사용할 수 있습니다. 언급 해 주셔서 감사합니다. 확실한 머리 긁는 도구.
다음은 내 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
/dev/stdin 2014-03-15
, 1 월 7 일 답변 -시간 여행자입니까?
/dev/stdin
하면 교체해야하므로, 존재하지 않는 /dev/stdin
다음 명령이 작동해야하므로, 따옴표없이, 단일 하이픈 '-'로 $ sed 's/oo/u/' fubar | diff -p fubar -
과$ sed 's/oo/u/' fubar | diff -p fubar - | patch
patch
잘리지 않을지 확실 하지 않습니다. 출력을 다른 파일에 저장 한 다음 cat
원본에 저장하는 것이 더 안전하다고 생각합니다.
당신이 원하는 것을 할 수는 없습니다 sed
. sed
해당 버전의 -i
파일을 수정하는 옵션을 지원하는 버전조차도 사용자가 명시 적으로 원하지 않는 것을 정확하게 수행합니다. 임시 파일에 쓴 다음 파일 이름을 바꿉니다. 그러나 아마도 당신은 그냥 사용할 수 있습니다 ed
. 예를 들어, 모든 항목 변경 foo
에 bar
파일의를 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
대부분의 용도에 적합해야합니다.
inline
그것을 호출 위와 같이 설명 :inline inputfile sed 's/foo/bar/g'
ed
실제로 제자리에있는 답변 만. 내가 처음으로 필요합니다 ed
. 감사합니다. 약간의 최적화는 사용 echo -e ",s/foo/bar/g\012 w"
또는 echo $',s/foo/bar/g\012 w'
쉘이 추가 tr
호출 을 피할 수있는 곳 입니다.
ed
실제로 수정 작업을 수행하지 않습니다. 에서 strace
출력, GNU는 ed
, 임시 파일을 생성하는 임시 파일에 변경 내용을 기록하고 하드 링크를 보존, 전체 원본 파일을 다시 작성합니다. 에서 truss
출력, 솔라리스 11은 ed
또한 임시 파일을 사용하지만 함께 저장시 원본 파일 이름으로 임시 파일의 이름을 변경 w
하드 링크를 파괴하는 명령.
ed
현재 맥 OS (모하비, 무엇이든 그 마케팅 용어 수단)와 함께 제공 여전히 하드 링크를 보존하고있다. YMMV
sed 는 내부 편집을 지원합니다. 보낸 사람 man sed
:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
예 :
hello.txt
텍스트 가있는 파일이 있다고 가정 해 봅시다 .
hello world!
이전 파일의 백업을 유지하려면 다음을 사용하십시오.
sed -i.bak 's/hello/bonjour' hello.txt
다음 hello.txt
과 같은 두 개의 파일로 끝납니다 .
bonjour world!
그리고 hello.txt.bak
오래된 내용으로.
사본을 유지하지 않으려면 확장 매개 변수를 전달하지 마십시오.
리디렉션 연산자 <>
를 사용하여 읽고 쓸 파일을 열 수도 있습니다 .
sed 's/foo/bar/g' file 1<> file
라이브보기 :
$ cat file
hello
i am here # see "here"
$ sed 's/here/away/' file 1<> file # Run the `sed` command
$ cat file
hello
i am away # this line is changed now
에서 읽기와 쓰기에 대한 배쉬 참조 설명서 → 3.6.10 열기 파일 설명 :
리디렉션 연산자
[n]<>word
파일 디스크립터 n에서 읽기 및 쓰기를 위해 또는 n이 지정되지 않은 경우 파일 디스크립터 0에서 이름이 확장 된 단어의 파일이 열립니다. 파일이 없으면 작성됩니다.
Skyfall에서 Moneypenny가 말한 것처럼 "때로는 옛날 방식이 가장 좋습니다." Kincade는 나중에 비슷한 것을 말했습니다.
$ printf ',s/false/true/g\nw\n' | ed {YourFileHere}
적절한 편집. 파일 쓰기를 위해 '\ nw \ n'을 추가했습니다. 지연 응답 요청에 대한 사과드립니다.
|
있습니다. @MattMontag
\n
. [range] s / <old> / <new> / <flag>는 대체 명령의 형태입니다. 다른 텍스트 편집기에서도 여전히 볼 수있는 패러다임 (좋아요, vim, ed의 직계 자손) 어쨌든 g
깃발은 "글로벌"이며 "보이는 각 줄의 모든 인스턴스"를 의미합니다. 범위 3,5
는 3-5 행을 봅니다. ,5
StartOfFile-5, 3,
3-EndOfFile 행 및 ,
StartOfFile-EndOfFile을 봅니다. "false"를 "true"로 바꾸는 모든 줄의 전역 대체 명령입니다. 그런 다음 쓰기 명령을 w
입력합니다.
-i
gnu sed의 옵션이지만 표준 sed에는 없습니다. 그러나 내용을 새 파일로 스트리밍 한 다음 파일 이름을 변경하여 원하는 파일이 아닙니다.