교체하기 전에 외부 프로그램을 통해 sed 캡처 그룹을 파이핑합니까?

교체하기 전에 외부 프로그램을 통해 sed 캡처 그룹을 파이핑합니까?

정규식의 RHS가 해당 프로그램의 출력과 동일 sed하도록 캡처링 그룹을 다른 프로그램으로 파이프하는 방법이 있습니까 ?\1

예를 들어 다음을 실행합니다.

sed 's/lorem ipsum \(foobar\)/\1/g' file.txt

"foobar" 를 다른 프로그램(예를 들어)을 통해 "faabar" tr 'o' 'a'로 연결하여 "lorem ipsum foobar"를 "lorem ipsum faabar"로 바꾸 나요 ?\1sed

이것은 단지 간단한 예일 뿐입니다. .tr

답변1

e(실행) 수정자를 사용하여 GNU sed를 사용할 수 있습니다 .

e이
명령을 사용하면 쉘 명령의 입력을 패턴 공간으로 파이프할 수 있습니다. 대체가 이루어지면 패턴 공간에 있는 명령이 실행되고 해당 출력이 패턴 공간을 대체합니다. 후행 줄 바꿈은 억제됩니다. 실행할 명령에 NUL 문자가 포함되어 있으면 결과가 정의되지 않습니다. 이것은 GNU sed 확장입니다.

(원천)

그러나 지정된 캡처 그룹이 아닌 전체 패턴 공간을 수행하고 교체하기 때문에 유용성이 제한됩니다. 그래서 당신은 꽤 추악한 농구를 뛰어 넘어야합니다.

전임자.

$ echo 'lorem ipsum foobar' | sed '
    s/\(lorem ipsum \)\(foobar\)/printf "%s%s" "\1" "$(echo "\2" | tr o a)"/e
  '
lorem ipsum faabar

답변2

내가 아는 한: 아니요.

패턴 공간은 다음을 사용하여 파일에 쓸 수 있습니다.

sed  '/example/w file'

하지만 캡처 그룹은 아닙니다. 다음 명령을 사용하여 외부 프로그램을 실행할 수 있습니다.

sed 'e ls'

다음 명령을 사용하여 파일을 읽을 수 있습니다

sed 'r file'

그러나 나는 당신이 요구하는 것을 달성하기 위한 유지 관리 가능한 방법을 보지 못했습니다. 솔직히 말해서, 당신은 여기서 유용할 수 있는 직전에 있습니다 sed.

awk아마도 여기서는 좀 더 유연할 수 있지만 perl@ikkachu가 이미 그의 의견에서 제안한 것처럼 이것이 최선의 선택입니다.

간단히 생각해보면, 그것이 얼마나 사소한 일인지 perl:

while (<>){
    if (/(.*)(pattern)(.*)/){
        $pre=$1;
        $pat=$2;
        $post=$3;
        $repl=`filter_pgm $pat`;
        print $pre . $repl . $post;
    }
    else {
        print;
    }
}

(Perl에 더 정통한 사람들을 위해: 나는 그것이 추악하고 아마도 프로덕션에서 실행하기 전에 많은 다듬질이 필요할 것이라는 것을 알고 있습니다)

관련 정보