Below an extract of the sample.pgn file

[Event "rated blitz match"]
[Site "Internet Chess Server"]
[Date "2015.08.20"]
[Round "?"]
[White "Villain"]
[Black "Hero"]
[Result "0-1"]
[WhiteElo "1643"]
[BlackElo "1616"]
[ECO "C39"]
[TimeControl "180"]

1.e4 e5 2.f4 exf4 3.Nf3 g5 4.h4 g4 5.Ne5 d6 6.Nxg4 Nf6 7.Nf2
{N} ( 7.Nxf6+ Qxf6 8.Nc3 Nc6 9.d4 Qxd4 10.Bxf4 Qxd1+ 11.Rxd1
Bg4 12.Be2 Bxe2 13.Ke2 
) Bh6 8.Qf3 Nc6 9.c3 Ne5 10.Qe2 Be6 11.d4 Bc4 12.Qc2 Bxf1 13.Rxf1
Ng6 14.Nh3 Ng4 15.Bxf4 Qxh4+ 16.Kd1 Nxf4 17.Nxf4 Ne3+ 18.Kd2
{Villain resigns} 0-1

[Event "rated blitz match"]
[Site "Internet Chess Server"]
[Date "2015.08.20"]
[Round "?"]
[White "Villain"]
[Black "Hero"]
[Result "0-1"]
[WhiteElo "1634"]
[BlackElo "1612"]
[ECO "C30"]
[TimeControl "180"]

1.e4 e5 2.f4 Bd6 {N} ( 2...Nf6 3.fxe5 Nxe4 4.Nf3 Ng5 5.d4 Nxf3+
6.Qxf3 Qh4+ 7.Qf2 Qxf2+ 8.Kf2 Nc6 9.c3 d6 10.exd6 Bxd6 11.Nd2
Be6 12.Ne4 Be7 13.Ng5 Bxg5 14.Bxg5 h6 15.Bh4 g5 16.Bg3 
) ( 2...Nc6 3.Nf3 f5 4.d3 d6 5.Nc3 Nf6 6.g3 g6 7.Bg2 Bg7 8.fxe5
dxe5 9.Bg5 h6 10.Be3 O-O 11.O-O 
) ( 2...exf4 3.Nf3 Nf6 4.e5 Nh5 5.d4 d5 6.Be2 Bg4 7.O-O Be7 8.Ne1
Bxe2 9.Qxe2 g6 10.Nd3 Nc6 11.c3 Qd7 12.Nxf4 Nxf4 13.Bxf4 h6 14.Be3
( 2...d6 3.Nf3 Nc6 4.Bb5 Bg4 5.h3 Bxf3 6.Qxf3 Nf6 7.fxe5 dxe5
8.Bxc6+ bxc6 9.d3 Bc5 10.Nd2 O-O 11.Nc4 Re8 12.Bg5 Re6 13.Rf1
Rb8 14.O-O-O 
) ( 2...d5 3.exd5 exf4 4.Nf3 Bd6 5.Nc3 Ne7 6.d4 O-O 7.Bd3 Nd7
8.O-O h6 9.Ne4 Nxd5 10.c4 Ne3 11.Bxe3 fxe3 12.c5 Be7 13.Bc2 Re8
14.Qd3 e2 15.Nd6 
) ( 2...Bc5 3.Nf3 d5 4.Nxe5 Nf6 5.d4 Bb6 6.exd5 Qxd5 7.Be3 Nc6
8.Nc3 Ba5 9.Be2 Qxg2 10.Bf3 Qh3 11.Nxc6 bxc6 12.Bxc6+ Kd8 13.Qf3
Qxf3 14.Bxf3 Rb8 15.O-O-O 
) 3.fxe5 Bxe5 4.Nf3 Nc6 5.d4 Bd6 6.Bc4 h6 7.O-O b6 8.e5 Be7 9.Nc3
a6 10.Nd5 Bb7 11.Nd2 g6 12.Nxe7 Qxe7 13.Bxf7+ Kd8 14.Bxg6 Qb4
15.c3 Qb5 16.Rf8+ Ke7 17.Rf7+ Kd8 18.Qf3 Nge7 19.Be4 Re8 20.Bd3
Qd5 21.Qf6 Qe6 22.Qxe6 dxe6 23.Be4 Rb8 24.Nf1 Rh8 25.Ng3 h5 26.Bg5
Kd7 27.Bxc6+ Bxc6 28.Rxe7+ Kd8 29.Rxe6+ Kd7 30.Re7+ Kc8 31.Rf1
Kb7 32.h4 Rbf8 33.Ref7 Rxf7 34.Rxf7 Bd5 35.Rd7 Bxa2 36.e6 Kc8
37.Re7 Rf8 38.Ne4 Bd5 39.Nf6 Bc4 40.Nd7 Rf5 41.Be3 Ra5 42.Bg5
Ra1+ {Villain forfeits on time} 0-1

I Would like to print every record in which the black player made a move marked with "{N}"

So far i've managed to get only a part of the game with this command:

awk 'BEGIN { RS=/\n\n/ } /( |\.{3}|^)([a-hBNKRQ][a-hBNKRQxX0-9\+\#\!\?]{1,7}|[O\-]{3,5})( |^)\{N\}/ { print $0 }' sample.pgn

but it only print partial information about the games, missing the beginning tags and some other informations:


1.e4 e5 2.f4 Bd6 {N} ( 2...Nf6 3.fxe5 Nxe4 4.Nf3 Ng5 5.d4 Nxf3+
6.Qxf3 Qh4+ 7.Qf2 Qxf2+ 8.Kf2 Nc6 9.c3 d6 1

1.e4 e5 2.f4 Bc5 3.Nf3 d6 4.c3 Nc6 {N} ( 4...Bg4 5.Bc4 Nf6 6.fxe5
Bxf3 7.Qxf3 dxe5 8.d3 Nc6 9.Bg5 a6 1

I don't know how to inform awk that a record is made of 2 blocks (Tags & Game) Can anyone help me to fix this?


You can set record separator to

                # empty line
                # empty line

just need to escape [ with double backslashes.

After that search for {N} string and if you find one print the whole record adding back \n\n[ if the record is not the first one.

Here is how I would do that:

awk 'BEGIN{RS="\n\n\\["}/\{N\}/{if(NR!=1) printf "\n\n["; print $0}' file


To match only black player with {N}:

awk 'BEGIN{RS="\n\n\\["}/\{N\} (\([^)]*\)[[:space:]])*[[:space:]]*[[:digit:]]/{if(NR!=1) printf "\n\n["; print $0}' file
  • Thanks a lot jimmij for your time and help, i got it working using this command: awk 'BEGIN{RS="\n\n\["}/([0-9]{1,3}\.)([a-hBNKRQ][a-hBNKRQxX0-9\+\#\!\?]{1,7}|[O\-]{3,5})( |\n|\r)\{N\}/{if(NR!=1) printf "\n\n["; print $0}' sample.pgn
    – Knudz
    Aug 20 '15 at 19:26
  • @Knudz Your command doesn't work for me, but in the meantime I came up with different approach - check the edit of my answer.
    – jimmij
    Aug 20 '15 at 19:34
  • After verification the command that i propose wasn't working for me either. I checked your solution but i'm still not satisfied as it doesn't filter white or black moves correctly. i came up with another solution to match black player: awk 'BEGIN { RS="\\[Event" ; FS="\n"} /( |\.{3}|\n|\r)([a-hBNKRQ][a-hBNKRQxX0-9\+\#\!\?]{1,7}|[O\-]{3,5})( |\n|\r)\{N\}/ {if(NR!=1) printf "[Event"; print $0}' sample.pgn
    – Knudz
    Aug 21 '15 at 17:57

Someone posted a response that partially addressed my issue but deleted it a few time later.

awk 'BEGIN{RS="\n\n\\["}/([0-9]{1,3}\.)([a-hBNKRQ][a-hBNKRQxX0-9\+\#\!\?]{1,7}|[O\-]{3,5})( |^|$\n^)\{N\}/{if(NR!=1) printf "\n\n["; print $0}' sample.pgn

The side to move is important. In this case it searches for white moves marked with "{N}". The only problem remaining with this command comes when for instance "white move" and "{N}" are separated with a line breaker like in the first game of this file

  • I've posted the answer, but later realized that you want to search for this string only for black side, what significantly complicate the problem. I will undelete my answer temporarily so that you could look and perhaps use some ideas.
    – jimmij
    Aug 20 '15 at 18:02
  • your solution is very good and almost solved my problem but i still can't get my regex to match the "{N}" if there's a line braker between the move and the "{N}". when i open my file with a text editor i can get it to work when checking the multiline box in the search tool box. with this regex: ([0-9]{1,3}\.)([a-hBNKRQ][a-hBNKRQxX0-9\+\!\?]{1,7}|[O\-]{3,5})( |^|$\n^)\{N\}. do you have any ideas on how i can make awk "understand" this multiline regex?
    – Knudz
    Aug 20 '15 at 18:13

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.