sed와 함께 -i 및 -E 옵션을 사용할 수 있습니까?

sed와 함께 -i 및 -E 옵션을 사용할 수 있습니까?

이런 파일이 있어요

public class Constants {
    public static final String PACKAGE_VERSION = '1.24.0.1';
}

스크립트를 실행하고 있어요

sed -E "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.2\'/g" force-app/main/default/classes/Constants.cls > temp.cls
mv temp.cls force-app/main/default/classes/Constants.cls

문자열 "1.24.0.1"을 "1.24.0.2"로 바꿉니다.

이 작업을 한 줄로 수행할 수 있습니까? 파일을 인라인 편집하는 awk대신 사용해야 합니까 ?sed

명령을 실행하려고 하면

sed -iE "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.3\'/g" force-app/main/default/classes/Constants.cls 

현재 파일을 인라인 수정하는 대신 Constants.clsE 파일이 생성되고 새 파일은 대체되지 않습니다.

명령을 실행하려고 하면

sed -Ei "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.3\'/g" force-app/main/default/classes/Constants.cls 

오류가 발생했습니다.

sed: 1: "force-app/main/default/ ...": invalid command code f

이 스크립트를 스크립트를 변경하지 않고 MacOS 및 Linux에서 실행하고 싶습니다.

사용해 보았지만 awk파일을 인라인으로 편집하는 방법을 이해하지 못합니까?

다음 명령을 실행하려고 하면

awk -v v="$version" '/PACKAGE_VERSION/{gsub(/[0-9]+(.[0-9]+){3}/,v)}1' force-app/main/default/classes/Constants.cls > force-app/main/default/classes/Constants.cls

이렇게 하면 내 파일이 비어 있게 됩니다.

답변1

다양한 구현은 내부 편집 옵션을 sed복제 하지만 불행히도 서로 다른 API를 사용합니다.-iperl

일부는 또한 (고급) 확장 정규식(POSIX 또는 그 변형)을 추가하거나 지원하고, 일부는 -E( 매우 ) 고급 Perl 유사 정규식(PCRE 또는 유사)을 추가하거나 지원하지만 동일합니다(가능하게 만드는 것 제외 ). POSIX 표준의 다음 버전이며 현재 점점 더 많은 구현에서 발견되고 있지만 보편적인 것은 없습니다.-r-R-P-E

여기에서는 실제 제품을 사용하여 이러한 모든 이식성 문제를 피할 수도 있습니다.

perl -i -pe "s{\bPACKAGE_VERSION\s*=\s*\K'\d+(\.\d+){3}'}{'1.24.0.3'}g" file

답변2

일부 sed에서는 (적어도FreeBSDMac에 있는 것), 이 -i옵션에는필수적인백업 파일에 사용되는 접미사를 설정하는 매개변수입니다. 쉘에 -i.suffix, or, 접미사를 붙이지 않고 쓸 수 있습니다. 여기서 or는 선택 사항이 아닌 and에 대한 인수로 or를 사용합니다.-i .suffix-i ""-iE-i -EE-E-i

다른 sed에서는 (적어도암소 비슷한 일종의 영양및 Busybox), 이 -i옵션에는 다음이 필요합니다.임의로 선택할 수 있는동일한 명령줄 인수 문자열에서 그 뒤에 오는 모든 항목에 접미사가 붙도록 인수에 접미사가 붙습니다. 일반적으로 -i[suffix]문서 형태로 제공 됩니다 . -i.suffix쉘에 쓰거나 접미사를 붙이지 않을 수도 있습니다 -i. 이 경우 접미사는 -iE여전히 생성되지만 두 가지 옵션이 E있습니다 -i -E.

두 경우 모두 -iE이는 접미사를 사용한다는 의미 E이며, FreeBSD/Mac에서는 -Ei ...다음 인수가 접미사(질문에 sed 프로그램에 넣은 접미사)로 사용됩니다.

백업이 없는 파일에 빈 접미사를 제공하려는 경우 두 가지 방법이 호환되지 않습니다. 이 경우 차이점을 알고 -i "" -EFreeBSD/Mac 또는 -i -EGNU와 함께 사용해야 합니다.

또는 파일을 백업하고 싶거나 상관없다면 -i.bak -E그 중 하나를 사용할 수 있습니다. (백업파일은 나중에 삭제할 수 있습니다.)

당신은 또한 볼 수 있습니다sed -i(제자리에서 편집)를 사용하여 이식성을 달성하는 방법은 무엇입니까?

답변3

-iE파일이 확장자로 백업되었음을 나타냅니다 "E". 다음을 사용해야 합니다.

sed -i.old -E ...

파일 filenamefilename.old.


sed귀하의 환경(macOS)에 대한 의견과 업데이트를 읽은 후 사용법에 대한 유용한 정보를 찾을 수 있는 몇 가지 링크를 추가했습니다 -i.


또한 버전을 바꾸려는 경우 다음을 사용하는 것이 더 읽기 쉬울 수 있습니다 awk.

awk -v v='1.24.0.2' '
  /PACKAGE_VERSION/{gsub(/[0-9]+(\.[0-9]+){3}/,v)}1
' force-app/main/default/classes/Constants.cls > file.tmp &&
  mv file.tmp force-app/main/default/classes/Constants.cls

참고: 입력 파일은 잘리기 때문에 대상으로 사용할 수 없습니다. 이는 게시물 끝에서 언급한 내용입니다. 도움을 주기 위해 임시 파일이 제공됩니다.

일반적으로 나는 or 를 사용할 때 내부 옵션(GNU의 경우)보다 awk임시 파일을 사용하는 것을 선호합니다 . 위 명령은 두 환경 모두에서 작동할 것으로 예상됩니다.sedawk

답변4

다음과 같이 이 작업을 수행할 수 있습니다. macOS의 경우 이 변수는 null이 아닌 값으로 설정되고 다른 시스템에서는 이 변수가 null 값으로 설정됩니다. 그런 다음 macOS인 경우 셸 확장은 인용된 null 값으로 확장되고, 그렇지 않으면 확장되지 않습니다(Linux 시스템).

os=$(case $(uname) in Darwin*)  echo x;; esac)
sed -Ei ${os:+""} -e "..." file

관련 정보