두 인스턴스 중 하나를 대체하기 위해 sed one-liner를 작성하려고 할 때
infra/helm/*/charts/*
또는
infra/helm/*/charts/
"infra/helm/*/charts/*"를 포함하는 파일에서 개행 문자와 다음과 같은 다른 텍스트 줄
infra/helm/*/charts/*
infra/helm/*/manifests/
이 패턴을 성공적으로 감지하고 이 코드 줄을 사용하여 일반 zsh(버전: zsh 5.7.1 (x86_64-apple-darwin19.0)) 터미널 창에서 패턴을 교체했습니다.
sed -E $'s/infra\\/helm\\/\\*\\/charts\\/(\\*)\*/infra\\/helm\\/\\*\\/charts\\/\\*\\\ninfra\\/helm\\/\\*\\/manifests\\//' myfile
(GNU) sed에 '-i' 플래그가 도입되었을 때 동작에 이상한 변화가 생겼습니다. 이 플래그를 사용하여 똑같은 라인을 실행할 때
(즉
sed -iE $'s/infra\\/helm\\/\\*\\/charts\\/(\\*)\*/infra\\/helm\\/\\*\\/charts\\/\\*\\\ninfra\\/helm\\/\\*\\/manifests\\//' datfile
)
파일이 수정되지 않은 것으로 나타났습니다. 일반적으로 나는 이것이 파일 권한의 일부 특이성이나 직접 터미널 항목이 아닌 스크립트를 호출하여 생성되는 프로세스 때문이라고 가정하지만 이상하게도 확인했습니다.
sed -iE $'s/infra\\/helm\\/\\*\\/charts\\/\\*/infra\\/helm\\/\\*\\/charts\\/\\*\\\ninfra\\/helm\\/\\*\\/manifests\\//' datfile
좋은 결과. (눈의 피로를 피하기 위해 이 라인의 유일한 차이점은
infra/helm/*/charts/*
수락하지 않고 패턴 일치로
infra/helm/*/charts/
)
이것이 왜 그런지 아는 사람이 있습니까? FWIW, 위의 zsh 버전을 인터프리터로 사용하는지 여부에 관계없이 이 동작이 여전히 존재한다는 것을 확인했습니다.또는 GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19) Copyright (C) 2007 Free Software Foundation, Inc.
대안으로. 몇 가지 해결 방법을 찾는 것이 그리 어렵지는 않겠지만, 저는 sed 기술을 향상시키고 싶기 때문에 이런 일이 발생하는 이유를 이해하는 것이 저에게 매우 중요할 것입니다.
실행 정보 덤프를 첨부했습니다.
strings $(which sed)
다음과 같은
$FreeBSD: src/usr.bin/sed/compile.c,v 1.28 2005/08/04 10:05:11 dds Exp $
$FreeBSD: src/usr.bin/sed/main.c,v 1.36 2005/05/10 13:40:50 glebius Exp $
$FreeBSD: src/usr.bin/sed/misc.c,v 1.10 2004/08/09 15:29:41 dds Exp $
$FreeBSD: src/usr.bin/sed/process.c,v 1.39 2005/04/09 14:31:41 stefanf Exp $
답변1
GNU sed의 -i
옵션은 백업에 사용할 접미사인 선택적 인수를 사용합니다. 이로 인해 sed -iE … datfile
이전 버전의 파일이 datfileE
.-E
해결 방법은 옵션을 별도로 전달하는 것입니다: sed -i -E …
또는 sed -E -i …
. ( -Ei
당신의 코드를 읽는 다음 사람이 싫다면 괜찮습니다.)
또는 백업 접미사( sed -E -i.bak …
)를 전달하면 스크립트를 FreeBSD sed 및 GNU sed 모두와 함께 사용할 수 있습니다. 이 접미사는 옵션에 필수 인수가 있기 때문에 BSD sed에 필요하며 GNU sed가 옵션 인수 가 아닌 선택적 인수로 처리하려면 -i
옵션과 동일한 명령줄 인수에 있어야 합니다( -i
및 사이에 공백 없음 ). 하나의 매개변수를 분리합니다 . 이는 백업 파일을 생성하는 부작용이 있습니다..bak
-i
sed