단일 sed 호출로 n번째 대체 항목만 인쇄하려면 어떻게 해야 합니까?

단일 sed 호출로 n번째 대체 항목만 인쇄하려면 어떻게 해야 합니까?

나 이거 있는데 어디서거의내가 하고 싶은 일을 해라

git show-branch --current 62cba3e2b3ba8e1115bceba0179fea6c569d9274 \
  | sed --quiet --regexp-extended 's/^.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/\1 \2/p' \
  | sed --quiet 2p #combine this into the previous sed to avoid another pipe/fork

그리고 출력

B-47120 java-11-take2

git show-branch이것을 출력하는 중

! [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix
 * [ccushing/B-47120-java-10-take1] B-48141 remove env prefix
--
 * [ccushing/B-47120-java-11-take2] B-48141 remove env prefix
+* [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix

sed에 파이프로 연결 되어 있다는 것을 알 수 있을 것입니다 sed. 왜냐하면 저는 두 번째 행만 원하기 때문입니다. 2p및 표현식을 단일 명령으로 결합하는 방법을 찾지 못했습니다 . 나는 모든 종류의 것을 시도했습니다. 이런 오류가 발생합니다

sed: can't read 2p: No such file or directory
sed: can't read s/^.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/\1 \2/p: No such file or directory

나는 여기 있다윈도우용 자식, 포함된 도구로만 가능합니다.

답변1

Sed는 한 번에 각 줄을 패턴 공간으로 읽습니다. 예약된 공간은 처음에는 비어 있다가 명시적으로 명령할 때만 채워지는 추가 슬롯입니다.

두 번째 교체 발생만 인쇄하려면,

sed -nE '/.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/{s//\1\2/;x;/./{x;p;q}}'
/pattern/{        # If the line matches the pattern
  s//replacement/ # Substitute the pattern by the replacement¹
  x               # Swap hold space and pattern space
  /./{            # If the pattern space is not empty, then
    x             # Swap hold space and pattern space
    p             # Print the line
    q             # Quit
  }
}

인쇄만 가능N1차 교체경기(여기 n=3),

sed -nE '/pattern/{s//replacement/;H;x;/(.*\n){3}/{s///p;q};x}'
/pattern/{        # If the line matches the pattern
  s//replacement/ # Substitute the pattern by the replacement¹
  H               # Append a newline and the pattern space to the hold space
  x               # Swap hold space and pattern space
  /(.*\n){3}/{    # If the pattern space contains 3 newline characters²
    s///p         # Delete all up to the last newline¹
    q             # Quit
  }
  x               # Swap hold space and pattern space
}

1:빈 패턴은 마지막으로 사용한 패턴과 동일합니다.. 2: 플래그를 사용하지 않는 경우 괄호와 중괄호(즉)를 이스케이프 처리하세요.
\(.*\n\)\{3\}-E

답변2

sed 표현식을 변수에 넣으면(마지막 표현식 제외 p):

subs='s/^.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/\1 \2/'

또한 git-branch출력을 다른 변수에 넣습니다.

outout='! [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix
 * [ccushing/B-47120-java-11-take2] B-48141 remove env prefix
--
 * [ccushing/B-47120-java-11-take2] B-48141 remove env prefix
+* [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix'

명령을 다음과 같이 줄일 수 있습니다(GNU sed 가정).

printf '%s\n' "$outout" | sed -nE "${subs}p"

이제 p다음으로 변경하면 ;T;2p요청한 작업이 수행됩니다( ;T;2{s/-/ /2g;p}대시 교체).

$ printf '%s\n' "$outout" | sed -nE "${subs};T;2p"
B-47120 java-11-take2

숫자 2는 두 번째 정규식 일치 항목이 아니라 두 번째 입력 줄을 나타냅니다.

일치하는 줄을 세어야 한다면 awk나 perl을 사용하거나 sed를 두 번 호출해야 합니다(이미 알아냈음).

관련 정보