사용 sed여부보이는임시 파일:

사용 sed여부보이는임시 파일:

내 프로젝트에서는 파일의 일부 기존 텍스트를 바꿔야 합니다.foo다음과 같은 다른 텍스트로fooofoo:

abc.txt
name
foo
foo1

그래서 나는 다음을 시도한다:

sed -i "s/foo/fooofoo/g" abc.txt

하지만 다음 오류가 발생합니다.

sed: 잘못된 옵션 --i

매뉴얼에서 다음을 사용해야 한다는 것을 알았습니다.

sed -i\ "s/foo/fooofoo/g" abc.txt

그러나 이것도 작동하지 않습니다.

나는 perland에서 대안을 찾았 지만, awkSolaris에서 해결책을 찾을 수 있다면 sed감사하겠습니다 .

저는 이 버전의 bash를 사용하고 있습니다.

GNU bash, 버전 3.2.57(1)-릴리스(sparc-sun-solaris2.10)

답변1

사용ed. 대부분의 플랫폼에서 작동하며 파일을 그 자리에서 편집할 수 있습니다. 대체 패턴을 기반으로 한 구문은 유사
하므로 다음과 같습니다.seded

ed -s infile <<\IN
,s/old/new/g
w
q
IN

답변2

GNU sed를 설치할 수 없으면 다음을 사용하십시오.

sed "s/foo/fooofoo/g" abc.txt >abc.tmp && mv abc.tmp abc.txt

이는 다음을 사용합니다.리디렉션sed의 출력을 임시 파일로 보냅니다. sed가 성공적으로 완료되면 abc.txt임시 파일을 덮어씁니다.

GNU sed의 소스코드에서 볼 수 있듯이, 이것이 바로 sed -i완료된 것입니다. 그래서 이것은 sed -i.

이미 존재할 가능성이 있는 경우 또는 유사한 유틸리티를 사용하여 임시 파일에 대한 고유 이름을 생성 abc.tmp할 수 있습니다 .mktemp

답변3

동등한 것을 원한다면 sed -i.bak매우 간단합니다.

GNU sed에 대해 다음 스크립트를 고려하십시오.

#!/bin/sh

# Create an input file to demonstrate
trap 'rm -r "$dir"' EXIT
dir=$(mktemp -d)
grep -v '[[:upper:][:punct:]]' /usr/share/dict/words | head >"$dir/foo"

# sed program - removes 'aardvark' and 'aardvarks'
script='/aard/d'

##########
# What we want to do
sed -i.bak -e "$script" "$dir"
##########

# Prove that it worked
ls "$dir"
cat "$dir/foo"

우리는 간단히 마커 라인을 다음과 같이 바꿀 수 있습니다.

cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"

그러면 기존 파일이 백업으로 이동되고 새 파일이 작성됩니다.

우리가 동등한 것을 원한다면

sed -i -e "$script" "$dir"  # no backup

그러면 조금 더 복잡해집니다. 표준 입력에서 읽기 위해 파일을 연 다음 링크를 해제하고 sed의 출력에 이를 대체하도록 지시할 수 있습니다.

( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )

이후에도 원래의 표준 입력을 계속 사용할 수 있도록 서브셸에서 이 작업을 수행합니다. 서브쉘 없이 입력을 전환하고 다시 전환하는 것이 가능하지만 나에게는 이 방법이 더 명확해 보입니다.

먼저 새 파일을 만드는 것보다 복사할 때 주의해야 한다는 점에 유의하세요 foo. 이는 파일에 여러 이름이 있고(예: 하드 링크가 있는 경우) 링크가 끊어지지 않도록 하려는 경우 중요합니다.

답변4

사용 sed여부보이는임시 파일:

별도의 생성을 피할 수 있습니다.보이는"임시 파일":

exec 3<abc.txt
rm abc.txt
sed 's/foo/fooofoo/' <&3 >abc.txt
exec 3<&-

설명하다

Unix 계열 시스템은 파일이 삭제될 때까지 디스크에서 파일 내용을 실제로 삭제하지 않습니다.둘 다파일 시스템에서 링크를 해제하고,그리고어떤 프로세스에서도 열리지 않습니다. 따라서 exec 3<셸에서 파일을 열어 파일 설명자 3 rm(파일 시스템에서 연결 해제)을 읽은 다음 sed파일 설명자 3을 입력으로 사용하여 호출할 수 있습니다.

이는매우이와 달리:

# Does not work.
sed 's/foo/fooofoo/' <abc.txt >abc.txt

차이점은 하나의 명령으로 이 작업을 수행하면 셸이 읽기 및 쓰기를 위해 동일한 파일을 열며 파일을 자르는 옵션이 있다는 것입니다. 파일은 여전히 ​​동일하므로 손실된 콘텐츠를 얻게 됩니다. 그러나 읽기 위해 연 다음 rm쓰기 위해 열고 동일한 경로 이름을 쓰기 위해 여는 경우 실제로는 동일한 경로 이름으로 새 파일을 생성하게 됩니다(그러나 새 inode 및 디스크 위치에 원본 파일이 남아 있기 때문입니다). open): 콘텐츠를 계속 사용할 수 있습니다.

그런 다음 완료되면 이전에 열었던 파일 설명자를 닫을 수 있습니다( exec 3<&-특수 구문이 수행하는 작업). 그러면 운영 체제가 해당 디스크 공간을 삭제(사용되지 않은 것으로 표시)할 수 있도록 원본 파일이 해제됩니다.

지침

이 솔루션에 대해 기억해야 할 몇 가지 사항은 다음과 같습니다.

  1. 콘텐츠는 한 번만 "탐색"할 수 있습니다.가지고 다닐 수 있는파일 설명자 내에서 쉘이 "보이는" 방식 - 프로그램이 무언가를 읽으면 다른 프로그램은 파일의 나머지 부분만 볼 수 있습니다. sed전체 파일을 읽 습니다 .

  2. 쉘/스크립트/sed가 완료되기 전에 종료되면 원본 파일이 손실될 가능성이 적습니다.

관련 정보