grep 출력에서 ​​일치하는 패턴을 제거하시겠습니까?

grep 출력에서 ​​일치하는 패턴을 제거하시겠습니까?

Bash를 사용하여 다음 명령을 실행합니다. declare -p | grep 'declare -- '그러면 전체 줄이 인쇄됩니다. 동일한 줄을 인쇄하고 싶지만 일치 항목 자체를 제외하고 싶습니다. 즉, ... | grep pattern | sed 's/pattern//'단일 명령으로 실행할 수 있나요? options 의 반대와 같습니다 -o.

내 명령의 출력은 다음과 같습니다.

...
declare -- MAX_CONNECTIONS_PER_SERVER="6"
declare -- OPTERR="1"
declare -- OSTYPE="linux-gnu"
...

하지만 나는 이것을 출력하고 싶습니다 :

...
MAX_CONNECTIONS_PER_SERVER="6"
OPTERR="1"
OSTYPE="linux-gnu"
...

보통은 그냥 파이프로 연결했지만 sed우연히 오늘은 파이프를 두 번 하고 싶었습니다. 매뉴얼 페이지를 살펴봤지만 이 작업을 수행할 수 있는 옵션이 없습니다.

일치하는 패턴을 따르는 줄 부분만 반환매우 비슷한 질문입니다. 어쩌면 반복적일 수도 있습니다. 내 것이 약간 좁다고 말할 수도 있습니다. 이는 내가 찾고 있는 패턴과 삭제하는 패턴이 동일하다는 것을 보장합니다. 삭제하고 싶습니다 x. 질문을 삭제하고 싶습니다 .*x.

답변1

그것은 다음과 같아야 합니다:

declare -p | sed -n 's/^declare -- //p'

그러나 출력을 구문 분석하는 이 방법에는 declare -p결함이 있습니다.

VAR=$'\ndeclare -- reboot #'예를 들어, 환경에 하나가 있고 해석을 위해 해당 출력을 셸에 공급한다면 어떻게 될까요?

또한 선언되었지만 값이 할당되지 않은 변수의 경우 bash: 이 인쇄되므로 declare -- VARNAME그 이후에는 declare reboot위 코드도 인쇄됩니다 reboot.

다음과 같이 변경할 수 있습니다.

declare -p | LC_ALL=C sed -n 's/^declare -- \(.*=\)/\1/p'

할당된 변수를 제한하지만 이는 여전히 개행 문자가 포함된 변수의 문제를 해결하지 못합니다(변수에만 해당되는 경우에도 일반적임 $TERMCAP).

대신 다음 해킹을 사용할 수 있습니다.

(
  export LC_ALL=C
  eval '
    declare()
      if [[ $1 = -- ]]; then
        printf "%s=%q\n" "${2%%=*}" "${2#*=}"
      fi'"
    $(declare -p | sed 's/[][()]/\\&/g')"
)

declare -p함수로 재정의한 후(첫 번째 인수가 있으면 두 번째 인수를 인쇄) 배열 및 연관 배열 표현에 사용되는 escapes ()의 출력을 평가합니다 [. bash의 출력은 과거에는 안전하지 않은 것으로 간주되었으며 특히 허용되는 줄 길이에 제한이 있는 구현의 경우 이스케이프를 추가하면 복잡성이 추가될 수도 있습니다.]declare--declare -psedsed


에서는 zsh다음을 수행할 수 있습니다.

typeset ${(k)parameters[(R)scalar]}

변수 정의 인쇄스칼라속성이 없습니다(심지어특별한...도 아니다묶음) 이것이 당신의 의도인 것 같습니다.

typesetsilent그러나 함수 내에서 호출되거나(이 경우 모든 변수를 로컬 변수로 선언함) 옵션이 활성화된 경우에는 아무런 효과가 없습니다.

이 문제를 해결하고 값 참조 방법을 더 효과적으로 제어할 수 있는 또 다른 방법은 다음과 같습니다.

() for 1 do print -r -- $1=${(Pq+)1}; done ${(k)parameters[(R)scalar]}

q+사용된 것과 유사한 인용 스타일을 제공합니다 typeset. qq사용더욱 안전한 인용 스타일이 출력을 셸에서 사용하려는 경우(zsh가 아니거나 동일한 버전이 아니거나 동일한 로케일 또는 OS/libc가 아닐 수 있음)

답변2

가능한 경우 다음을 사용하십시오 grep -P.

declare -p | grep -Po 'declare -- \K.*'

일반적으로 변수에 개행 문자가 포함될 수 있으므로 이러한 접근 방식은 잘 작동하지 않으며 이를 사용하여 grep구문 오류를 발생시킬 수 있습니다.

예를 들면 다음을 참조하세요.

declare -- IFS="    
"

답변3

Perl을 사용하면 쉽게 할 수 있습니다.

declare -p | perl -lne'/^declare -- (.*)/ && print $1'

당신이 사용하는 경우확인하다, 다음과 같이 할 수 있습니다.

declare -p | ack '^declare -- (.*)' --output='$1'

답변4

declare -p |awk -F "--" '/declare --/{print $NF}'

산출

 MAX_CONNECTIONS_PER_SERVER="6"
 OPTERR="1"
 OSTYPE="linux-gnu"

관련 정보