sed는 매번 단어 경계만 일치합니다.

sed는 매번 단어 경계만 일치합니다.

명령 파일에 대체 목록을 유지하고 싶습니다.

subs.sed

s/hello/foo/g
s/world/bar/g

저는 이렇게 운영해요sed -i -f subs.sed file.txt

file.txt에서부터 .hello worldfoo bar

그러나 나는 이런 일이 발생하는 것을 방지하고 싶습니다. 만약 file.txt그렇다면 helloworld위의 두 가지 대체 중 어느 것도 발생하는 것을 원하지 않습니다. 현재 출력은 foobar이지만 출력은 helloworld.

명령 파일에서 단어 경계를 수동으로 지정할 수 있습니다.

s/\<hello\>/foo/g
s/\<world\>/bar/g

그러나 나는 이 문서를 이렇게 장황하게 설명하기보다는 가능한 한 사람이 읽을 수 있도록 만들고 싶습니다.

sed전체 단어만 일치 하도록 하는 명령줄 옵션이 있습니까 ? 물론 명령줄을 편집하는 다른 방법(sed를 실행하기 전에 명령 파일에서 sed를 실행합니까? 하지만 복잡한 대체 항목을 구문 분석하는 것이 걱정됩니다)이 있으면 좋을 것입니다.

이것은 Ubuntu 22.04의 GNU sed입니다.

답변1

sed첫째, GNU( Linux 시스템의 기본값) 를 실행하는 경우 sed사용법을 단순화할 \b수도 \>있으며 \<이렇게 하면 이해하기가 더 쉬워질 수 있습니다.

$ cat subs.sed 
s/\bhello\b/foo/g
s/\bworld\b/bar/g

즉, 설명하는 대로 수행할 수는 없을 것 같지만 해결 방법은 다음과 같습니다. 파일을 그대로 유지하되 전처리 단계를 추가합니다.

$ sed -e 's|/|/\\<|' -e 's|/|\\>/|2' subs.sed 
s/\<hello\>/foo/g
s/\<world\>/bar/g

여기서는 두 개의 명령을 에 전달합니다 . 첫 번째 명령은 의 sed첫 번째 항목을 대체 하고 두 번째 명령 은 두 번째 항목을 대체합니다 . 이스케이프 문자 가 필요 하므로 문자 그대로 백슬래시로 처리하려면 다른 문자를 추가하여 이스케이프해야 합니다 . 그런 다음 두 번째 명령 끝에 있는 것은 "이 줄이 두 번째로 나타나는 경우 이 작업을 수행합니다"를 의미합니다. 예를 들어 설명하는 것이 더 쉽습니다.//\<//\>\\>\\<\\2

$ echo "......" | sed 's/./A/'
A.....
$ echo "......" | sed 's/./A/2'
.A....
$ echo "......" | sed 's/./A/3'
..A...
$ echo "......" | sed 's/./A/4'
...A..

<()따라서 해당 명령을 사용하면 다음을 이해하는 셸을 사용하는 한 실제 교체를 실행하기 위한 작은 별칭을 만들 수 있습니다.프로세스 교체:

$ sed -f <(sed -e 's|/|/\\<|' -e 's|/|\\>/|2' subs.sed) file.txt 
foo you
the bar
helloworld

그리고 삶을 좀 더 쉽게 만들기 위해 셸의 초기화 파일( ~/.bashrc예:)에 다음 줄을 추가하여 별칭을 만들 수 있습니다.

alias mysub="sed -i -f <(sed -e 's|/|/\\<|' -e 's|/|\\>/|2' /path/to/subs.sed)"

새 터미널을 열면 이제 실행하여 mysub file예상되는 출력을 얻을 수 있습니다.

관련 정보