Mac OSX의 sed와 다른 "표준"sed의 차이점은 무엇입니까?


답변:


43

쉘 유틸리티의 동작은 유닉스 변형들 사이에서 사소한 방식으로 다릅니다. 복잡한 역사를 가진 많은 유닉스 변형 이 있습니다 . POSIX 표준 및 단일 UNIX 사양 과 같은 표준화 노력 이 있습니다 . 오늘날 대부분의 시스템은 단일 UNIX 사양 버전 3 으로 알려진 POSIX : 2001 을 약간만 변경하고 확장하여 구현합니다. 단일 Unix 스펙은 학습서가 아니지만 명령이 수행중인 작업에 대한 아이디어가 있으면 버전 3을 읽을 수 있습니다. 일부 기능이 표준인지 또는 특정 시스템의 확장인지 확인하기 위해이를 참조 할 수 있습니다.

대부분의 유닉스 사용자는 Linux를 사용하고 다른 변형을 사용하지 않았습니다. Linux에는 GNU 유틸리티 가 포함되어 있으며이 유틸리티는 종종 표준에 대한 많은 확장 기능을 가지고 있습니다. 따라서 리눅스에서는 작동하지만 다른 확장 프로그램에는 의존하지 않기 때문에 다른 유니스에서는 작동하지 않는 많은 코드가 있습니다.

sed와 관련하여 sed Single Unix 사양 에서 모든 시스템이 지원해야하는 최소값, 구현에서 지원하는 사항 에 대한 시스템 설명서 페이지 및 대부분의 사람들이 사용 하는 GNU sed 매뉴얼 을 참조하십시오.

GNU sed의 비표준 확장 중 하나는 여러 명령을 함께 실행하는 것입니다. 예를 들어,이 GNU sed 프로그램은을 포함하는 모든 행을 인쇄 a하지만 처음으로 변경 b됩니다 c.

sed -ne '/a/ {s/b/c/g; p}'

{}전체 휴대 그래서, 당신이 그들을 지정해야, 실제로는 별도의 명령입니다 중 하나 (파일에서), 또는 별도의 별도의 줄에 -e인수 (명령 행)에. 명령 구분 기호가없고 명령 구분 기호로 {사용 ;하는 것이 일반적인 확장입니다. 이전에 명령 구분 기호가 없기 때문에 }일반적이지 않은 확장입니다. 이것은 표준을 준수합니다.

sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'

이것은 비표준이지만 일반적으로 허용됩니다.

sed -ne '/a/ { s/b/c/g; p; }'

비표준이지만 일반적인 확장은 대체 텍스트 \n에서 줄 바꿈을 의미하는 것입니다 s(regexp에서 사용하는 것이 표준 임). 이식 가능한 방법은 sed 스크립트에 백 슬래시-줄 바꾸기를 포함시키는 것입니다. 또 다른 일반적인 확장자는 \+, \?\|regexps '에 대부분의 사람과 교대에서 하나 또는 그 이상을 의미하는 것으로, 이식 가능한 기본 정규 표현식 에는이 중 어느 것도 없습니다. 예를 들어, 첫 번째 명령은 연속 된 공백 시퀀스를 줄 바꿈으로 바꾸는 이식 불가능한 방법입니다. 두 번째 명령은 표준을 준수하는 명령입니다.

sed -e 's/ \+/\n/'
sed -e 's/  */\
/'

GNU 확장에 관한 모든 경우에 비표준 사용법입니다. GNU sed자체는 표준에 의해 허용 된 (하지만 불필요하고 지정되지 않은) 작업을 수행하므로 준수합니다. 호환되지 않고 POSIXLY_CORRECT환경 에서 실행하는 것이 도움이 될 수 있습니다. 마찬가지로 s/[\n]//g백래시와 n문자를 제거해야 하지만 대신 줄 바꿈을 제거 해야합니다 . 또는 N마지막 행 의 명령 동작 .
Stéphane Chazelas

sed -ne '/a/ { s/b/c/g; p; }'표준 2016 년 이후 표준입니다. 항상 휴대 할 수있었습니다. 참조 austingroupbugs.net/view.php?id=944&nbn=7
스테판 Chazelas가에게

60

OS X은 현재 2005 년부터 FreeBSD sed와 함께 제공됩니다. 아래 차이점의 대부분은 다른 BSD sed 버전에도 적용됩니다.

OS X의 sed는 -EERE에 사용 되며 GNU sed는 -r. GNU sed에서 -E별명입니다 -r(4.2에 추가, 4.3까지 문서화되지 않음). 로 FreeBSD와 NetBSD의 SED의 새로운 버전을 모두 지원 -E하고 -r. OpenBSD sed 만 지원합니다 -E.

-i ''OS X의 sed에서는 작동하지만 GNU sed에서는 작동하지 않습니다. -iGNU sed, 최신 버전의 NetBSD, OpenBSD sed에서는 작동하지만 OS X sed에서는 작동 하지 않습니다. -i -e둘 다 작동하지만 FreeBSD의 경우 파일 이름에 추가 된 sed원본 파일을 백업 -e합니다 (그리고 하나 이상의 표현식을 전달할 필요가 없습니다 sed).

GNU sed는 해석과 같은 순서 탈출 \t, \n, \001, \x01, \w,와 \b. OS X의 sed 및 POSIX sed는 해석 만하고 \n의 대체 부분은 아닙니다 s.

GNU sed는 \|, \+\?BRE를 해석 하지만 OS X의 sed 및 POSIX sed는 그렇지 않습니다. \(, \), \{, 및 \}POSIX BRE 있습니다.

GNU sed는 ;전에 생략 하거나 개행을 허용 }하지만 OS X의 sed는 생략 합니다.

i(삽입), a(추가) 및 c(변경) 뒤에 OS X의 sed 및 POSIX의 백 슬래시와 줄 바꿈이 있어야하지만 GNU sed에는 없습니다. GNU의 SED에 의해 삽입 된 텍스트 후 누락 된 줄 바꿈을 추가 i, a또는 c나오지도하지만, OS X 용의하지 않습니다. 예를 들어 sed 1iaGNU 대안이 sed $'1i\\\na\n'있습니다.

예를 들어 printf a|sed -n p, OS X에는 sed에는 개행을 추가하지만 GNU에는 sed에는 없습니다.

OS X의 sed는 I(대소 문자 구분) 또는 M(멀티 라인) 수정자를 지원하지 않습니다 . 최신 버전의 FreeBSD sed 지원 I.

OS X의 sed는 -s( --separate), -u( --unbuffered) 또는 -z( --null-data)를 지원하지 않습니다 .

이다 나오지 GNU에서 지원하지 않는 한 BSD 옵션 -a하게, w대신 파일을 절단의 파일에 추가합니다.

OS X의 sed에서 작동하지 않는 GNU sed 명령의 예 :

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a shell command
sed -n l0 # 0 disables wrapping

4
-i -eOSX에서는 작동하지 않습니다. 그것은 interpets -e접미사로.
Chris Martin

3
@ChrisMartin 예, OS X 버전 -i에서는 빈 문자열이더라도 항상 접미사가 필요합니다. 그래서 -i '' -e작동합니다.
waldyrious

@waldyrious OSX에서만 작동합니다.
Chris Martin

예, 그것은 그 버전의 단점입니다 :)
waldyrious

3
" -i -e문과 함께 작동합니다." 귀하의 답변에 크로스 플랫폼 솔루션이 있습니다. 분명히 없습니다.
leondepeon 2012 년

5

Linux와 Mac에서 동일한 스크립트 작업을 수행하는 가장 좋은 방법은 다음과 같습니다.

sed -i.bak -e 's/foo/bar/' -- "${TARGET}" &&
  rm -- "${TARGET}.bak"

또는 perl어디에서 왔는지 사용하십시오 -i. perl -Tpi -e 's/foo/bar/' -- "$TARGET"
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.