#! /usr/bin/gawk -f # Last edited on 2022-11-03 15:48:36 by stolfi (abort >= 0) { exit(abort); } BEGIN { abort = -1; if (bdir == "") { arg_error("must define {bdir}"); } # Splits one or more ".bib" files into files "{bdir}/{yyyy}/{key}.bib", # one per entry, where the {yyyy} is deduced from the key junkname = ( bdir "/extra.bib" ); # File name for lines not part of any entry. fname = ""; # File name for current entry, or "". yyyy = ""; # Year of current entry, or "". key = ""; # Key of current entry, or "". } /^[@]/ { if (fname != "") { close(fname); data_error(" entry \"" key "\" not terminated"); } key = $0; gsub(/[,].*$/, "", key); gsub(/^[@].*{/, "", key); if (key !~ /^[a-z][-a-zA-Z0-9]+$/) { data_error("invalid key \"" key "\""); } yy = key; gsub(/^[-a-zA-Z]*[-]/, "", yy); gsub(/[-][-a-zA-Z0-9]*$/, "", yy); if (yy !~ /^[0-9][0-9]$/) { data_warn("invalid year \"" yy "\" in key \"" key "\", assuming \"yyyy\"" ); yyyy = "yyyy"; } else { yyyy = (yy+0 <= 22 ? yy+2000 : yy+1900) } system("mkdir -p " bdir "/" yyyy) fname = (bdir "/" yyyy "/" key ".bib") print > fname # Overwrite file if already there. next; } /^ *year *[=]/ { yyyy_ck = $0; gsub(/^[^0-9]*/, "", yyyy_ck); gsub(/[^0-9]*$/, "", yyyy_ck); if (yyyy_ck !~ /^([1][7-9][0-9][0-9]|[2][0][012][0-9])$/) { data_warn("invalid \"year\" field in entry \"" key "\" = \"" yyyy_ck "\""); } else if (yyyy_ck != yyyy) { data_warn("inconsistent \"year\" field in entry \"" key "\", \"" yyyy "\" != \"" yyyy_ck "\""); } } /^ *[}] *$/ { if (fname == "") { data_error("spurious close brace in entry \"" key "\""); } print >> fname close(fname); key = ""; yyyy = ""; fname = "" next; } // { if (fname != "") { print >> fname; } else { print >> junkname; } next; } END { if (abort >= 0) { exit(abort); } if (fname != "") { close(fname); data_error(" entry \"" key "\" not terminated"); } } function arg_error(msg) { printf "** %s\n", msg > "/dev/stderr"; abort = 1; exit(abort); } function data_error(msg) { data_msg("**", msg); abort = 1; exit(abort) } function data_warn(msg) { data_msg("!!", msg); } function data_msg(tag, msg) { printf "%s:%d: %s %s\n", FILENAME, FNR, tag, msg > "/dev/stderr"; printf " [[%s]]\n", $0 > "/dev/stderr"; }