awk 和正则表达式处理 pgn 国际象棋游戏文件

awk 和正则表达式处理 pgn 国际象棋游戏文件

下面摘录了样本.pgn文件

[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

我想打印黑人玩家做出标记为“{N}”的每一步记录

到目前为止,我只能使用以下命令获得游戏的一部分:

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

但它只打印有关游戏的部分信息,缺少开始标签和一些其他信息:

"]

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
"]

我不知道如何通知 awk 记录由 2 个块组成(标签和游戏)任何人都可以帮我解决这个问题吗?

答案1

您可以将记录分隔符设置为

                # empty line
                # empty line
[

只需要用[双反斜杠转义即可。

之后搜索{N}字符串,如果找到一个,则打印整个记录,\n\n[如果该记录不是第一个记录,则添加回来。

我将这样做:

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

编辑:

仅匹配黑人玩家{N}

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

答案2

有人发布了一个回复,部分解决了我的问题,但几次后又删除了。

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

移动的一侧很重要。在这种情况下,它搜索标有“{N}”的白色棋步。该命令剩下的唯一问题是当“white move”和“{N}”用换行符分隔时,例如在该文件的第一个游戏中

相关内容