単一の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。なぜなら、私は2行目だけが欲しいからです。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

私はここにいるWindows用の子、付属のツールでのみ可能です。

答え1

Sed は一度に各行をパターン空間として読み込みます。予約されたスペースは、最初は空であり、明示的に命令した場合にのみ満たされる追加のスロットです。

2番目の交換が発生した場合のみ印刷するには、

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
  }
}

印刷のみ可能N一次交替試合(ここ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 は、2 番目の正規表現一致ではなく、2 番目の入力行を表します。

一致する行を数える必要がある場合は、awkまたはperlを使用するか、sedを2回呼び出す必要があります(すでに見つけました)。

関連情報