sed의 대체 문자열은 어떻게 명령의 출력이 되나요?

sed의 대체 문자열은 어떻게 명령의 출력이 되나요?

다음 sed 명령은 Hello각 입력 줄의 끝에 텍스트를 추가하는 데 도움이 됩니다.

<complex_query> | sed "s,$,Hello,"
Output:
myvar1: Hello
myvar2: Hello

grep wow data.txt | cut -d: -f2이제 대신 출력을 사용하고 싶습니다 .Hello

어떻게 이럴 수있어?

아래는 내가 시도했지만 작동하지 않는 것입니다.

<complex_query> | sed "s,$,(grep wow data.txt  | cut -d: -f2),"

예상되는 원하는 출력:

myvar1: <output of grep wow data.txt  | cut -d: -f2 command>
myvar2: <output of grep wow data.txt  | cut -d: -f2 command>

답변1

다른 명령의 인수에서 명령의 출력(후행 개행 제외)을 사용하려면 다음을 사용할 수 있습니다.명령 대체1970년대 후반 Bourne 쉘에 도입된 기능입니다.

Bourne 쉘에서도 구문 은 `cmd...`.csh

(from) 을 기반으로 하는 것과 같은 최신 sh및 유사한 쉘에서는 구문이 반대입니다(이전 버전과의 호환성을 위해 Bourne 구문도 지원하지만).shkshzshbashash$(...)

rc-like 쉘 에서 구문은 다음과 같습니다.`{cmd...}

fish쉘 에서는 (cmd ...)큰따옴표 안에 사용할 수 없습니다. 버전 3.4.0부터는 큰따옴표 안에 which를 사용하는 fish것도 지원됩니다 .$(cmd...)

명령 대체는 종종 명령의 출력을 서로 다른 셸 간에 다르게 분할하여 여러 인수가 명령에 전달되고 일부(대부분의 Bourne과 유사한 셸 포함)는 결과 단어에 대해 글로빙(!)을 수행하기도 합니다. 이는 일반적으로 ( rcshell² 또는 < 3.4.0³와 같은 것이 아닌) 큰따옴표 안에 명령 대체를 배치하여 방지할 수 있습니다 .fish

그래서 여기 있습니다:

  • POSIX 유사 쉘 또는 fish3.4.0+:

    <complex_query> | sed "s,\$,$(grep wow data.txt | cut -d: -f2),"
    
  • rc- 조개와 유사함:

    nl = '
    '
    <complex_query> | sed 's,$,'``($nl){grep wow data.txt | cut -d: -f2},
    
  • csh/ tcsh:

    <complex_query> | sed "s,\$,`grep wow data.txt | cut -d: -f2`,"
    
  • fish< 3.4.0

    <complex_query> | sed 's,$,'(grep wow data.txt | cut -d: -f2 | string collect),
    

이제 &및 문자는 \명령의 교체 부분에서 특별하므로 (여기에 사용된 구분 기호) 및 개행 문자(개행 문자가 존재할 수 있는 경우)와 함께 이스케이프되어야 합니다. 위와 같이 나누어 탈출했습니다.)seds\,cshrc

바라보다"sed" 대체에 삽입된 문자열이 모든 메타 문자를 이스케이프하는지 확인하는 방법그것에 대해.

또 다른 방법은 특수 문자에 대해 걱정 perl하지 않고 사용하는 것입니다 .sed

<complex_query> | REPL="$(cmd...)" perl -lpe '$_ .= $ENV{REPL}'

(이것은 POSIX와 유사한 쉘을 가정합니다)

또는 perlCollect cmd의 출력 자체를 허용할 수도 있습니다(자신의 출력을 사용하고 `...`있는 경우 후행 줄 바꿈을 자릅니다 chomp).

<complex_query> | perl -lpe 'BEGIN{chomp ($repl = `cmd...`)}; $_ .= $repl'

ksh93최신 버전은 다른 버전과 다른 형식 mksh도 지원 ${ ...; }하지만 에서처럼 fish하위 쉘 환경을 도입하지 않습니다.

²클래스 쉘에는 강한 따옴표(내부적으로 확장이 발생할 수 없음)라는 rc한 가지 유형의 따옴표만 있습니다 . 분할을 위한 구분 기호 목록을 지정하는 구문을 사용하여(여기서는 비어 있음)을 사용하여 분할을 방지 '...'할 수 있지만 이렇게 하면 후행 개행 트리밍도 방지됩니다.``(){cmd ...}``(sep1 sep2){cmd ...}

3 또한 csh/tcsh에서는 "`cmd ...`"개행 문자 분할이 여전히 수행됩니다.

관련 정보