Bash One-Liners for Lichess Puzzle Sleuthing
Chess tactics and shell scripts make an oddly satisfying pairing. Here are the bash one-liners I use to spot my own games inside the ever-growing Lichess puzzle set.
Pull Down the Data
# Replace parsnips with your Lichess handle
declare -r USERNAME="parsnips"
curl -L "https://lichess.org/games/export/${USERNAME}" -o "lichess_${USERNAME}.pgn"
curl -L "https://database.lichess.org/lichess_db_puzzle.csv.bz2" -o lichess_db_puzzle.csv.bz2
Decompress the Puzzle Archive
bzip2 -d lichess_db_puzzle.csv.bz2
Capture Every Puzzle Game URL
cat lichess_db_puzzle.csv \
| cut -d ',' -f9 \
| cut -d '#' -f1 \
| sed -e 's|/black||' \
| sort -u \
> puzzle-games
The pipeline slices the puzzle metadata, trims color suffixes, and deduplicates the URLs so each source game appears once.
Extract Your Own Games
grep -e 'Site' "lichess_${USERNAME}.pgn" \
| grep -o -e '\\".*\\"' \
| sed -e 's|"||g' \
| sort -u \
> my-games
PGN headers keep the game URL in the Site
field—we peel it out with grep and leave a neat list to compare.
Reveal the Overlap
grep -F -f my-games puzzle-games
That single command highlights every Lichess puzzle sourced from your own play. I like to feed the results into a study so I can relive the tactics and annotate the critical ideas.
Why It Works
Each line sticks to portable Unix tools: curl
handles downloads, cut
and sed
reshape CSV fragments, and grep -F -f
performs the fast set intersection. Once you’ve scripted the workflow, updating your study is a nightly ritual—no GUI, just a few keystrokes and a fresh set of puzzles to celebrate (or cringe at).
Happy hacking, happy checkmating.