-i 옵션이있는 sed 명령은 Mac에서 실패하지만 Linux에서는 작동합니다.


303

sedLinux에서 텍스트를 검색 / 바꾸기 위해 다음 명령을 성공적으로 사용했습니다 .

sed -i 's/old_link/new_link/g' *

그러나 Mac OS X에서 시도하면 다음과 같은 결과가 나타납니다.

"명령 c는 \ 다음에 텍스트가 필요합니다"

내 Mac이 정상적인 BASH 셸을 실행한다고 생각했습니다. 뭐야?

편집하다:

@High Performance에 따르면, 이것은 Mac sed의 BSD 풍미가 다르기 때문에 BSD 에서이 명령을 어떻게 복제 sed합니까?

편집하다:

이것을 일으키는 실제 예는 다음과 같습니다.

sed -i 's/hello/gbye/g' *

1
이것은 sed데이터에서 "c"를 명령으로 본다는 것을 의미합니다 . 변수를 사용하고 있습니까? 실제 명령과 처리중인 일부 데이터를보다 자세히 나타내는 내용을 게시하십시오. 을 수행하여이 오류에 대한 간단한 데모를 얻을 수 있습니다 echo x | sed c.
추후 공지가있을 때까지 일시 중지되었습니다.

@Dennis, 위의 간단한 명령은 처리하는 데이터가 html 및 css 파일을 포함하여 전체 웹 사이트 (모든 이미지 링크를 변환하고 있음)이지만 ...
Yarin

답변:


397

-i옵션 을 사용하는 경우 백업 확장명을 제공해야합니다.

당신이 가지고 있다면:

File1.txt
File2.cfg

명령 ( -i및 새로운 버전의 Mac 및 GNU에서 작동 ''하도록 -e하기 위해 및 사이에 공간이 부족함 ) :

sed -i'.original' -e 's/old_link/new_link/g' *

다음과 같은 2 개의 백업 파일을 작성하십시오.

File1.txt.original
File2.cfg.original

모든 경우에 작동하는 sed 명령을 혼합하여 찾을 수 없기 때문에 백업 파일 작성을 피하는 휴대용 방법은 없습니다.

  • sed -i -e ...- -e백업 을 생성 할 때 OS X에서 작동하지 않습니다
  • sed -i'' -e ... -OS X 10.6에서는 작동하지 않지만 10.9+에서는 작동합니다.
  • sed -i '' -e ... -GNU에서 작동하지 않습니다

참고 모든 플랫폼에서 작동하는 sed 명령이없는 경우 다른 명령을 사용하여 동일한 결과를 얻을 수 있습니다.

예 : perl -i -pe's/old_link/new_link/g' *


4
나는 같은 문제가 있었다. 이 솔루션에 감사드립니다. 그러나 '-i'에 대한 설명을 찾기 위해 'man sed'로 시도한 경우 백업을 무시하기 위해 -i``를 사용하는 것에 대한 것은 없습니다. 이것이 나의 첫 비난입니다. 둘째, "명령에 따라 \ 다음에 텍스트가 나옵니다"라는 오류가 표시되면 '-i'옵션에 대한 백업 이름이 필요하다고 직접 알려주지 않는 이유는 무엇입니까? 그런 일은 어디에서나 발생합니다. 오류가 발생하지만 오류가 발생하지 않은 이유는 설명이없는 매뉴얼을 검색하십시오. 그런 다음 다른 사람도 찾을 수 있도록 Google에서 동일한 문제가 있습니다. 내 말은, 왜 매뉴얼에 예를 들어주지 않습니까?
lukmac

또는 오류가 발생한다는 정보가없는 메시지 대신 오류가있는 이유를 알려주십시오. 이 의견을 읽을 수 있다면 모든 툴 제작자에게 제안합니다.
lukmac

5
@lukmac 알 sed수 있듯이 백업 접미사를 제공했습니다. 백업 접미사는 s/old_link/new_link/g입니다. 그 후의 다음 인수는 편집 명령입니다. 명령을 백업 이름으로 해석했기 때문에 첫 번째 파일 이름을 편집 명령으로 사용했지만 유효하지 않습니다.
Barmar

2
이것이 항상 문제가됩니까? Apple이 OSX와 함께 GNU sed의 대안 / 패키지를 만들 수있는 방법이 있습니까? 아니면 GNU sed를 지원할 수 sed -i '' -e ...없습니까?
blong

5
sed -i'' -e맥 10.14에서 예상대로 작동하지 않는 것 같습니다
MoOx


55

이것은 sed의 GNU 및 BSD 버전 모두에서 작동합니다.

sed -i'' -e 's/old_link/new_link/g' *

또는 백업 :

sed -i'.bak' -e 's/old_link/new_link/g' *

-i옵션 뒤에 공백이 없습니다 . (GNU sed에 필요)


7
첫 번째는 OSX에서 작동하지 않습니다 (방금 10.6.8에서 테스트했습니다)
marcin

4
OS X (10.10.3)의 경우, 처음에는 -e 접미사가 붙은 백업 파일을 만들었습니다. 좋지 않다. 두 번째는 Ubuntu와 OS X 사이에서 일관되게 나를 위해 일한 유일한 것입니다. 백업 파일은 원하지 않았으므로 rm삭제 한 직후 명령 을 실행 해야했습니다.
Brendan

1
첫 번째 줄은 10.10에 사용할 수있는 공간으로 다시 작성해야합니다. sed -i'' ...=>sed -i '' ...
Daniel Jomphe

3
@DanielJomphe 그러나이 공간을 추가하는 것은 GNU sed에서 작동하지 않습니다
Brice

1
@marcin 첫 번째는 OSX 10.11.2에서도 작동합니다. 백업 파일을 생성 한 후 나중에 제거해야합니다. 나중에 파일 이름을 알 필요가 없으므로 두 번째가 더 좋아 보입니다.
vikas027

41

Mac에서 동일한 문제가 있었고 다음과 같이 해결했습니다 brew.

brew install gnu-sed

로 사용

gsed SED_COMMAND

sed별명으로 설정할 수도 있습니다 gsed(원하는 경우).

alias sed=gsed

3
Ohad Kravchick 정확히 같은 대답 을 한 이유는 무엇 입니까?
gniourf_gniourf

1
이와 같이 별칭을 설정하는 것은 좋은 생각이 아닙니다
SantaXL

1
해당 추출 페이지에서 권장하는 별칭 대신 PATH = "$ (brew --prefix) / opt / gnu-sed / libexec / gnubin : $ PATH"
y.luis

24

또는 Mac에 gsed라고하는 sed의 GNU 버전을 설치하고 표준 Linux 구문을 사용하여 사용할 수 있습니다.

이를 위해 gsed포트를 사용하여 설치하십시오 (없는 경우 http://www.macports.org/ 에서 구 하십시오 ) sudo port install gsed. 그런 다음 실행할 수 있습니다sed -i 's/old_link/new_link/g' *


24
.. 또는 homebrew를 사용하는 경우gnu-sed
Sudar

1
@Sudar에게 감사합니다.
앤드류 스완

9

Mac은 실제로 BASH 셸을 실행하지만 이는 처리중인 sed의 구현에 대한 질문입니다. Mac에서 sed는 BSD에서 제공되며 일반적인 Linux 상자에서 찾을 수있는 sed와 미묘하게 다릅니다. 나는 당신을 제안합니다 man sed.


3
BSD의 문제 -을 지적 주셔서 감사하지만 아주 문맹 나오지도있어 그냥 사람에서 내 - 명령 빠른 한눈에 대한 빠른 수정이 필요 나에게 아무것도 이야기하지 않습니다
Yarin

5
@Yarin-아니요. man sed를 간단히 살펴보면 아무 것도 말하지 않습니다. 더 길게보십시오.
High Performance Mark

21
대부분의 SO 답변은 남성 어딘가에 묻혀 있습니다. 그러나 똑똑한 사람들의 답변이 필요한 바쁜 사람들도
마찬가지입니다.

9

Sinetris의 대답은 옳지 만 find명령 과 함께 사용 하여 변경하려는 파일을 더 구체적으로 지정합니다. 일반적으로 이것은 작동해야합니다 (osx에서 테스트 됨 /bin/bash).

find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;

복잡한 프로젝트에서 사용 sed하지 않고 일반적으로 사용하는 경우 find효율성이 떨어집니다.


-exec아주 좋습니다! 마지막에 슬래시가 실제로 필요한지 궁금합니다.
Ye Liu

2
@YeLiu은 다음 않고 \는이 ;나는 그런 시도 할 때 쉘에 의해 해석되었다
INC SERV를-

2

sedMacOS (MacOS 10.12에서 테스트)와 다른 OS의 차이점 을 처리하는 기능을 만들었습니다 .

OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
    if [ "$OS" = 'Darwin' ]; then
        # for MacOS
        sed -i '' -e "$1" "$2"
    else
        # for Linux and Windows
        sed -i'' -e "$1" "$2"
    fi
}

용법:

$(replace_in_file 's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' "./mysql/.env")

어디:

, Delimeter입니다

's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' 패턴이다

"./mysql/.env" 파일 경로


1

환경 변수를 템플릿 파일에 적용하는 방법은 다음과 같습니다 (백업 필요 없음).

1. 나중에 교체 할 {{FOO}}로 템플릿을 만듭니다.

echo "Hello {{FOO}}" > foo.conf.tmpl

2. {{FOO}}를 FOO 변수로 바꾸고 새 foo.conf 파일로 출력하십시오.

FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf

macOS 10.12.4Ubuntu 14.04.5 모두 작동


0

다른 답변에서 알 수 있듯이 백업 파일을 만들지 않고 OS X 및 Linux에서 sed를 이식 가능하게 사용할 수있는 방법이 없습니다. 그래서 대신이 루비 원 라이너를 사용했습니다.

ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml

내 경우에는 rake작업 (예 : Ruby 스크립트 내부) 에서 호출해야 하므로이 추가 인용 수준을 사용했습니다.

sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}

-1
sed -ie 's/old_link/new_link/g' *

BSD 및 Linux 모두에서 작동


3
이것은 리눅스에서 다른 파일 이름을 e추가 하여 생성합니다
Brice

1
깨진 것이 좋습니다.
sorin

Mac 및 Linux에서 작동합니다. 이 솔루션의 문제점은 무엇입니까?
이슬람 아자 브

아니요, Mac BSD Sed에서는 작동하지 않습니다. 파일 이름에 'e'가 추가 된 백업 파일을 만듭니다.
Jesper Grann Laursen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.