このデータからn番目の「チャンク」を抽出できますか?

このデータからn番目の「チャンク」を抽出できますか?

stdout次のテキストブロックがたくさんあります。

% QUESTION
Who played drums for The Beatles?


% QUESTION
Who played
guitar

for The Beatles?


% QUESTION
Who played

bass for The Beatles

?

ここでのアイデアは、ファイルが「チャンク」に分割され、各チャンクが1行で始まるということです% QUESTION。このデータのn番目のチャンクを印刷するスクリプトを作成したいと思います。

たとえば、配布はnthchunk 3印刷する必要があります。

Who played

bass for The Beatles

?

どうすればいいですか?

答え1

awk正規表現をレコード区切り文字 ( ) としてサポートするRS実装 (例: GNU) では、awk次のことができます。

awk -v n=3 -v RS='(\n+|^)% QUESTION\n' 'NR == n+1 {print; exit}' < questions.txt

答え2

GNU sed-Eこの問題を解決するには、拡張正規表現パターンを使用します。基本的な考え方は、連続した%問題の行とその間の行をパターン空間に蓄積することです。カウンタは一連の点の形で記憶空間に保持される。

chunk=2
sed -E ':loop
  /%/,/%/N
  /%.*%/!{
    /%/!d;$!bloop
    s/$/\nfiller/
  }
  G;s/$/./
  /\n[.]{'"${chunk}"'}$/bend
  h;s/.*\n//;x
  s/.*(\n.*)\n.*$/\1/;D
  :end
  s/^[^\n]*\n+(\S.*\S)(\n.*){2}$/\1/
  q
' file

あるいは、Perl は slurp モードにあり、FS は問題行に設定されます。 @F配列の要素はブロックでなければなりません。

perl \
  -F'/(?:^|\n+)\%\h+QUESTION\n+/' \
  -pals -0777 \
  -e '$_=$F[$n]' \
-- -n="${chunk}" ./file;

出力:

Who played
guitar

for The Beatles?

答え3

このデータのn番目のチャンクを印刷するスクリプトを作成したいと思います。

RS合計を設定すると、ORS次のような各質問が得られます。

この必要マルチ文字RS用GNU awk

awk -v RS='% QUESTION'  -v ORS='' '/\<drums\>/ {print $0}' file

Who played drums for The Beatles?
  • またはbass
awk -v RS='% QUESTION'  -v ORS='' '/\<bass\>/ {print $0}' file

Who played

bass for The Beatles

?
  • またはguitar:
awk -v RS='% QUESTION'  -v ORS='' '/\<guitar\>/ {print $0}' file

Who played
guitar

for The Beatles?
  • または、ブロックの代わりに数字を使用してください。
$ nchunk=3
awk -v nchunk="$nchunk" -v RS='% QUESTION'  -v ORS=''  'NR==nchunk+1 {print $0}' file

Who played

bass for The Beatles

?

関連情報