A lightweight Bash utility that reports the popularity rank of a given first name in a specific year using the U.S. Social Security baby‑name dataset (subset included: 1880–1908).
Language: Bash (POSIX shell compatible)
Dataset:us_baby_names/yobYYYY.txt(CSV lines:Name,Gender,Count)
OS: macOS / Linux
Dependencies: GNU grep (ggrep) with PCRE support (-P), coreutils
mahadhsn-us-baby-names/
├── README.md
├── bn # main executable (Bash)
└── us_baby_names/ # SSA data subset (1880–1908)
├── yob1880.txt
├── yob1881.txt
└── ...
Data format per line:
<name>,<gender>,<count>
Mary,F,7065
John,M,9655
# macOS (Homebrew): ensure GNU grep is available as `ggrep`
brew install grep
# make bn executable
chmod +x bnIf ggrep is not on your PATH after installation, add it:
echo 'export PATH="/opt/homebrew/opt/grep/libexec/gnubin:$PATH"' >> ~/.zshrc
exec zsh -lThe script uses
ggrep -P(PCRE). On Linux,grep -Pmay work; if so, replaceggrepwithgrep.
bn <year> <assigned gender: f|F|m|M|b|B>
<names>
year: 4‑digit (e.g.,1901) — must exist inus_baby_names/gender:f|Ffemale,m|Mmale,b|Bbothnames: one or more names provided via stdin (interactive or piped)
Interactive (single name):
$ ./bn 1901 m
John
1901: John ranked 1 out of 1219 male names.Pipe multiple names:
$ printf "John\nMary\nMahad\n" | ./bn 1888 b
1888: John ranked 1 out of 1015 male names.
1888: Mary ranked 1 out of 793 female names.
1888: Mahad not found among male names.
1888: Mahad not found among female names.Help & usage:
./bn --help
./bn # prints usage and exits with code 1- For
gender = m|Morf|F, prints one line with rank and population size (or "not found"). - For
gender = b|B, prints up to two lines: one for male and one for female. - Ranks are case‑insensitive (
-iflag) and match whole tokens using PCRE word boundaries (\bname\b).
0— success1— invalid number of arguments (also prints usage)2— badly formatted year or gender3— badly formatted name (stdin token not alphabetic)4— no data for the given year
The script validates arguments before reading names from stdin when possible, and validates each name as it’s processed.
- Ranking logic:
- Total names per gender computed via
ggrep -iP '^.+,G,.+$' | wc -l - The rank is the line number of the first match in the gender‑filtered list:
ggrep -inP "\b<name>\b,G,.+$" | ggrep -oP '^[0-9]+' - Uses PCRE for word boundaries and case‑insensitivity.
- Total names per gender computed via
- Batch mode: Reads stdin line‑by‑line and splits on whitespace, enabling flexible input (one or multiple names per line).
- Portability: Script assumes
ggrep(GNU grep) for-PPCRE; macOS’s BSDgreplacks-P.
- Operations are linear in file length; each query filters the year file twice (once per gender when needed).
- For larger datasets (post‑1908), consider pre‑computing maps or using
awkto stream once per gender.
- Happy paths: known top names by year/gender; mixed‑case input.
- Error cases: invalid year (
19ab), invalid gender (x), invalid name (John3), missing year file. - Both‑gender mode: name present in one gender only.
- Dataset in this repo covers 1880–1908 only. Add more
yobYYYY.txtfiles for later years. - Names with punctuation/hyphens are treated as invalid (alphabetic only).
MIT