0

How can I get a paragraph with the string and the following paragraph with awk?

The file looks like this:

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player A"]
[Black "Player B"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player B"]
[Black "Player C"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player C"]
[Black "Player A"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

This command returns the paragraphs I want:

> awk '/Player A/' RS="\n\n" ORS="\n\n" file.pgn

How can I add the following paragraph with the moves of the games?

Like this:

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player A"]
[Black "Player B"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player C"]
[Black "Player A"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1
1
  • 1
    Can you add an example of the output you desire? – YetAnotherUser Feb 21 at 20:42
3
$ awk -v RS= -v ORS='\n\n' '/"Player A"/{c=2} c&&c--' file
[Event "Chess game"]
[Date "2021.01.08"]
[White "Player A"]
[Black "Player B"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player C"]
[Black "Player A"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

See printing-with-sed-or-awk-a-line-following-a-matching-pattern for details on how that and related idioms work.

I made the regexp to test for Player A from your question more robust and I used RS=<null string> instead of RS='\n\n' so it'll work in any awk, not just gawk.

2

awk in paragraph mode

awk -v RS= -v ORS="\n\n" '
  /"Player A"/ { var=NR+1;print }
  var==NR
' file

perl in paragraph mode (-00)

perl -00 -ne '
  print s/\z/<>/re
    if /"Player A"/ && !eof;
' file

sed collect chunks of non empty lines in the hold space. And from there once the target para is identified print till the nearest empty line (=> print next record)

sed -e '
  /./,/^$/!d
  H;/./d;x;s///
  /"Player A"/!d
  :n;n;/^$/!bn
' file

Results:

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player A"]
[Black "Player B"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

[Event "Chess game"]
[Date "2021.01.08"]
[White "Player C"]
[Black "Player A"]
[Result "0-1"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 5. O-O b5 6. Bb3 Nf6
7. Nxe5 Nxe5 8. d4 Ba7 9. dxe5 Ng8 10. Qd5 0-1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.