Post

How to Automatically Replace Numeric Citations with Citation Keys in LaTeX Using PowerShell

A practical guide for researchers and students to automate the conversion of numeric citations to proper citation keys in LaTeX documents using PowerShell scripting.

How to Automatically Replace Numeric Citations with Citation Keys in LaTeX Using PowerShell

We’ve all been there. You’re wrapping up a paper in LaTeX, and you realize your document is full of \cite{1}, \cite{2}, \cite{3}… but your .bib file uses proper keys like smith2023keyword. Now you’re staring at dozens — maybe hundreds — of citations that need fixing, one by one.

I ran into this exact problem while working on a manuscript last year. After spending way too long doing it by hand (and making a few mistakes along the way), I wrote a short PowerShell script to handle it automatically. It saved me a ton of time, and I think it might help you too.

What’s the Problem, Exactly?

Here’s what it usually looks like. Your .tex file has something like this:

1
Recent advances have revolutionized the field \cite{1}\cite{2}.

Meanwhile, your .bib file has proper entries like:

1
2
3
4
5
6
@article{smith2023keyword,
  title={Title of the First Paper},
  author={Smith, John and Lee, Jane},
  journal={Journal Name},
  year={2023}
}

See the mismatch? Your document says \cite{1}, but it should say \cite{smith2023keyword}. When you only have a few references, it’s no big deal. But when you have 50 or 100? That’s where things get painful.

The Fix: A Simple PowerShell Script

The idea is straightforward — we tell the script which number maps to which citation key, and it does all the replacing for us. No more Ctrl+H marathons.

Before You Start

You’ll need:

  • A Windows PC (PowerShell is already there)
  • Your .tex file with numeric citations
  • Your .bib file so you know the correct keys
  • About 5–10 minutes

Step 1: Set Up Your Citation Mapping

Take a look at your .bib file and note down which number corresponds to which citation key. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%1
@article{smith2023keyword,
  title={Title of the First Paper},
  author={Smith, John and Lee, Jane},
  journal={Journal Name One},
  year={2023}
}

%2
@inproceedings{doe2024analysis,
  title={Title of the Second Paper},
  author={Doe, Alice and Park, James},
  booktitle={Proceedings of the Conference Name},
  pages={100--115},
  year={2024}
}

So 1 maps to smith2023keyword, 2 maps to doe2024analysis, and so on. Just keep adding entries for as many references as you have.

Step 2: The PowerShell Script

Here’s the full script. You can copy it as-is and just update the mapping part with your own citation keys:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# LaTeX Citation Replacement Script
# Replaces \cite{number} with \cite{citationkey}

# Create the citation mapping (add as many as you need)
$citationMap = @{
    '1' = 'smith2023keyword'
    '2' = 'doe2024analysis'
    # '3' = 'your_next_key_here'
}

# Interactive file selection
Write-Host "Please select your LaTeX file..." -ForegroundColor Cyan
Add-Type -AssemblyName System.Windows.Forms

$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.Filter = "LaTeX files (*.tex)|*.tex|All files (*.*)|*.*"
$openFileDialog.Title = "Select your LaTeX file"

if ($openFileDialog.ShowDialog() -eq 'OK') {
    $inputFile = $openFileDialog.FileName
    $outputFile = $inputFile -replace '\.tex$', '_updated.tex'

    Write-Host "Selected: $inputFile" -ForegroundColor Green
} else {
    Write-Host "No file selected. Exiting." -ForegroundColor Red
    exit
}

# Read the file
Write-Host "`nProcessing file..." -ForegroundColor Cyan
$content = Get-Content $inputFile -Raw

# Count citations
$beforeCount = ([regex]::Matches($content, '\\cite\{\d+\}')).Count
Write-Host "Found $beforeCount numeric citations" -ForegroundColor Yellow

# Replace citations using regex
$pattern = '\\cite\{(\d+)\}'
$result = [regex]::Replace($content, $pattern, {
    param($match)
    $number = $match.Groups[1].Value
    $key = $citationMap[$number]

    if ($key) {
        return "\cite{$key}"
    } else {
        Write-Host "Warning: No mapping for citation $number" -ForegroundColor Yellow
        return $match.Value
    }
})

# Save the result
$result | Set-Content $outputFile -NoNewline

# Show results
Write-Host "`n✓ Replacement complete!" -ForegroundColor Green
Write-Host "Output: $outputFile" -ForegroundColor Green

Write-Host "`nPreview of replacements:" -ForegroundColor Magenta
$matches = [regex]::Matches($result, '\\cite\{[a-z]+\d{4}[a-z]+\}') | Select-Object -First 3
foreach ($m in $matches) {
    Write-Host "  $($m.Value)" -ForegroundColor White
}

Step 3: Running the Script

One-Time Setup

If you’ve never run a PowerShell script before, you’ll need to allow it first. Just do this once:

  1. Press Windows + X and click Windows PowerShell (Admin)
  2. Type: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
  3. Hit Y and Enter

That’s it. You won’t need to do this again.

Actually Running It

  1. Save the script above as replace-citations.ps1 — put it wherever you like
  2. Right-click the file and choose Run with PowerShell (or open PowerShell and type .\replace-citations.ps1)
  3. A file browser pops up — pick your .tex file
  4. The script creates a new file called yourfile_updated.tex with all the replacements done

Your original file stays untouched, so there’s no risk of losing anything.

See It in Action

Click to see a Before → After example Before (input.tex):
\documentclass{article}
\begin{document}

Some introductory text about the research topic \cite{1}\cite{2}.

Further discussion on methodology and results \cite{2}, particularly when
applied to analysis and evaluation \cite{1}.

\bibliographystyle{plain}
\bibliography{references}
\end{document}
After (input_updated.tex):
\documentclass{article}
\begin{document}

Some introductory text about the research topic \cite{smith2023keyword}\cite{doe2024analysis}.

Further discussion on methodology and results \cite{doe2024analysis}, particularly when
applied to analysis and evaluation \cite{smith2023keyword}.

\bibliographystyle{plain}
\bibliography{references}
\end{document}

Under the Hood (For the Curious)

You don’t need to understand this part to use the script, but if you’re curious about how it works, here’s a quick breakdown.

The Hashtable

1
2
3
4
$citationMap = @{
    '1' = 'smith2023keyword'
    '2' = 'doe2024analysis'
}

Think of this as a dictionary. The script looks up each number and finds the matching citation key.

The Regex Pattern

1
$pattern = '\\cite\{(\d+)\}'

This tells the script what to look for:

  • \\cite — the literal text \cite
  • \{ and \} — the curly braces
  • (\d+) — one or more digits (this is what gets captured and replaced)

The Replacement

1
2
3
4
5
6
[regex]::Replace($content, $pattern, {
    param($match)
    $number = $match.Groups[1].Value
    $key = $citationMap[$number]
    return "\cite{$key}"
})

For every match, the script grabs the number, looks it up in the dictionary, and swaps it with the real citation key.

What If I Have a Lot of References?

No problem. Just keep adding lines to the mapping:

1
2
3
4
5
6
7
$citationMap = @{
    '1' = 'smith2023keyword'
    '2' = 'doe2024analysis'
    # ... keep going
    '50' = 'lee2024algorithms'
    '100' = 'wang2023method'
}

The script handles them all the same way, whether you have 5 or 500.

A Few Tips from Experience

Do:

  • Always test with a small file first before running it on your full thesis
  • Double-check your number-to-key mapping — a wrong mapping means wrong citations
  • Use meaningful citation keys like smith2023keyword instead of vague ones like ref1

Don’t:

  • Reuse the same citation key for different numbers
  • Forget the quotes around numbers in the hashtable — write '1', not 1
  • Worry if you see a warning — it just means the script couldn’t find a mapping for that number, and it leaves the original citation as-is

Common Issues (and Quick Fixes)

“Scripts are disabled on this system” Run this in PowerShell as Admin:

1
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

“Nothing got replaced” Check that your citations actually use the \cite{number} format. Also make sure there are no extra spaces inside the braces — \cite{ 1 } won’t match.

“Warning: No mapping for citation X” You’re using citation number X in your document but haven’t added it to the $citationMap. Either add it or leave it — the script won’t break anything.

Bonus: Combining Multiple Citations

The script handles back-to-back citations just fine:

Click to see an example Before:
Multiple studies \cite{1}\cite{2} have shown...
After:
Multiple studies \cite{smith2023keyword}\cite{doe2024analysis} have shown...
Quick tip: After running the script, you can manually merge these into a single cite command:
Multiple studies \cite{smith2023keyword,doe2024analysis} have shown...
This gives you a cleaner output — [1,2] instead of [1][2].

Wrapping Up

Look, nobody enjoys spending their afternoon doing find-and-replace on citation keys. This script handles it in seconds, and once you’ve set up the mapping, you can reuse it anytime you work with the same bibliography.

Give it a try on your next paper — I think you’ll be surprised how much time it saves.


Ready to Use It?

  1. Copy the script into a .ps1 file
  2. Update the $citationMap with your own citations
  3. Run it on your .tex file
  4. That’s it — you’re done

Tip: Take a few minutes to get your citation mapping right. It’s worth the upfront effort — it’ll save you hours down the road.

Warning: Always keep a backup of your original .tex file before running any script on it, especially if it’s your final thesis or dissertation!


Got questions or ran into something unexpected? Drop a comment below — happy to help.

This post is licensed under CC BY 4.0 by the author.