Site icon Ampersand Tutorials

NCBI EDirect Tutorial: Query PubMed, GenBank and SRA from the Command Line

Streams of glowing data flowing through pipes into a central node, representing command-line data retrieval

NCBI holds the largest collection of biological sequence and literature data in the world, and almost every bioinformatics project starts with getting something out of it. Pointing and clicking through the web interface works for one accession. It does not work for two thousand accessions, and it leaves no record of what you asked for.

EDirect — Entrez Direct — is NCBI’s official command-line interface to the same databases. It exposes search, fetch, linking and parsing as separate programs that you chain with pipes, which means every step of your data retrieval is a command in a script you can commit.

Installation

sh -c "$(curl -fsSL https://ftp.ncbi.nlm.nih.gov/entrez/entrezdirect/install-edirect.sh)"

# The installer prints a line to add to your shell profile:
export PATH="$HOME/edirect:$PATH"

# Verify
esearch -version
efetch -version

On a managed system, prefer conda, which pins the version and keeps EDirect out of your home directory:

conda create -n edirect -c bioconda entrez-direct
conda activate edirect

Whichever route you take, verify with a trivial query before building anything on top of it. If esearch hangs, the problem is usually a proxy or firewall, not your query.

The five programs and what each does

ProgramJobTypical use
esearchSearch a database, return matching IDsTurn a query string into UIDs
efetchDownload records by IDGet FASTA, GenBank, abstracts, run info
elinkFollow links between databasesFind SRA runs for a BioProject
esummaryFetch compact metadata documentsTitle, organism, length, date
xtractParse XML into columnsBuild a TSV from esummary output

The pattern is always the same: esearch produces UIDs, and something downstream consumes them. Once that clicks, EDirect stops feeling like five tools and starts feeling like one.

Searching PubMed and getting usable output

# How many papers match?
esearch -db pubmed -query "single cell RNA-seq[Title/Abstract] AND 2025[PDAT]" |
  grep -o '<Count>[0-9]*</Count>'

# Download abstracts as text
esearch -db pubmed -query "CRISPR delivery[Title]" |
  efetch -format abstract > abstracts.txt

# Structured metadata as a table
esearch -db pubmed -query "long read sequencing[Title]" |
  esummary |
  xtract -pattern DocumentSummary \
    -element Id -tab "\t" -element PubDate -tab "\t" -element Title

The final command is the workhorse. xtract -pattern says which repeating XML element to treat as a record, -element names the field, and -tab inserts a separator. Redirect to a file and you have a reproducible literature table instead of a screenshot.

Field tags are case-sensitive and unforgiving. [Title], [Title/Abstract], [PDAT] for publication date, [Organism] for taxonomy, and [Accession] all work; [title] silently changes the meaning of your query. When a search returns zero results, test the same terms in the web interface first and compare.

Fetching sequences

# One accession
esearch -db nucleotide -query NC_000913.3 | efetch -format fasta > ecoli.fa

# Whole genome record with annotations
esearch -db nucleotide -query NC_000913.3 | efetch -format gbwithparts > ecoli.gb

# Proteins matching an organism and a keyword
esearch -db protein -query "insulin[Title] AND Homo sapiens[Organism]" |
  efetch -format fasta > insulin.fa

# How many hits before you download them all?
esearch -db protein -query "kinase[Title] AND Mus musculus[Organism]" |
  efetch -format fasta |
  grep -c '^>'

That last pattern — count before you commit — has saved more disk space and more network time than any other habit in this tutorial. A loose query against protein can easily return hundreds of megabytes.

From a list of accessions to a multi-FASTA

cat accessions.txt
# NM_000546.6
# NM_000546.5
# NM_001354689.3

while read -r acc; do
  esearch -db nucleotide -query "$acc" | efetch -format fasta
done < accessions.txt > genes.fa

One query per accession is slow but honest, and it makes failures visible: if an accession has been retired, you see an empty result for that line rather than a silently shortened file. For hundreds of accessions, post them all at once instead:

cat accessions.txt | epost -db nucleotide | efetch -format fasta > genes.fa

Getting SRA run data without downloading reads

The runinfo format is the most useful thing most people never find. It returns the metadata table for every sequencing run in a project — run accessions, sample names, platform, read counts, file sizes — without touching a single FASTQ.

# All runs in a BioProject
esearch -db sra -query PRJNA257197 | efetch -format runinfo > runinfo.csv

# Run accessions only
esearch -db sra -query PRJNA257197 |
  efetch -format runinfo |
  cut -d, -f1 | tail -n +2 | grep -v '^$' > runs.txt

# Total size before you decide to download
awk -F, 'NR>1 {sum+=$5} END {print sum/1024/1024/1024 " GB"}' runinfo.csv

Column 5 in runinfo.csv is the size in bytes; check the header rather than trusting that number blindly, since NCBI has changed column order historically. Once you have runs.txt, hand it to the SRA toolkit — the download pattern is covered in our public sequencing data guide.

Linking between databases

elink follows NCBI’s internal cross-references. The classic use: you have a paper and want the sequences it deposited, or you have a BioProject and want its publications.

# PubMed ID -> linked nucleotide records
esearch -db pubmed -query "Escherichia coli O157 genome[Title]" |
  elink -target nuccore |
  efetch -format docsum |
  xtract -pattern DocumentSummary -element AccessionVersion -element Title

# Gene -> protein products
esearch -db gene -query "TP53[Gene] AND human[Organism]" |
  elink -target protein |
  efetch -format fasta > tp53_proteins.fa

Rate limits, API keys, and being a good citizen

NCBI allows three requests per second without a key and ten with one. The limit is not a suggestion: exceed it and you receive errors or, worse, silently truncated results that look like a biological finding.

# Request a key at https://account.ncbi.nlm.nih.gov/settings/
export NCBI_API_KEY="your_key_here"

# Each EDirect program picks the key up from the environment.
# Slow a batch down when you are near the limit:
while read -r acc; do
  esearch -db nucleotide -query "$acc" | efetch -format fasta
  sleep 0.2
done < accessions.txt > genes.fa

Batch epost plus efetch is far kinder than a loop: one search request instead of hundreds. Use the loop only when you need per-accession error handling.

The failures you will actually hit

SymptomCauseFix
Search returns 0Invalid field tag or over-specific queryTest the same terms in the web UI, then simplify
Empty FASTA with a valid accessionRetired or suppressed recordCheck the accession page; use the current version suffix
Truncated output on big queriesRate limitingAdd an API key and batch with epost
efetch: command not foundPath line not added to profileAdd export PATH="$HOME/edirect:$PATH"
XML instead of a tableMissing xtract stagePipe through xtract -pattern

One more quiet trap: esearch with no -db defaults to PubMed, so a nucleotide query that returns nothing may simply have been sent to the wrong database. Always name the database explicitly, even when it feels redundant.

Why this belongs in your project, not your browser history

The real benefit of EDirect is not speed. It is that accessions.txt plus a five-line script fully documents how your dataset was assembled, and a reviewer can rerun it. That is the difference between data you found and data you can defend.

Retrieval is the first step of a longer chain: quality control, alignment, quantification, statistics. If you want that chain mapped out in order, with the decisions that matter at each stage, Ampersand Academy covers it from raw accession to interpreted result.

Practice

  1. Count how many human mitochondrial genomes exist in nucleotide for a given year, without downloading any records.
  2. Build a TSV of the ten most recent papers on a topic you care about, with ID, date and title.
  3. Take one BioProject and produce both a run list and a total download size in GB.
  4. Find the protein products of three genes using only elink, never opening a browser.

Is EDirect the same as the Entrez Programming Utilities (E-utilities)?

EDirect is a command-line layer built on top of E-utilities. E-utilities are the underlying HTTP API; EDirect wraps them in Unix-style programs so you can pipe results instead of writing HTTP requests yourself. Anything EDirect does can be done with E-utilities and more code.

Do I need an NCBI API key?

Not for occasional interactive use. You do need one for any batch job that makes more than roughly three requests per second. Keys are free from your NCBI account settings and raise the limit to ten requests per second.

How do I download FASTQ files with EDirect?

You do not — EDirect fetches metadata, not raw reads. Use efetch -format runinfo to get run accessions, then download the reads with the SRA Toolkit (prefetch and fasterq-dump) or from ENA, which serves FASTQ directly.

Why does my esearch return zero results when the website finds papers?

Almost always a field tag problem. Field tags are case-sensitive, and an unsupported tag changes the query meaning rather than raising an error. Remove the tag, confirm the result count, then add tags back one at a time.

Can EDirect fetch a whole genome with annotations?

Yes, with efetch -format gbwithparts for GenBank records, which includes features and sequence. Note that very large eukaryotic genomes may be impractical to fetch this way; downloading assembly files from the FTP site is usually better.

Is it acceptable to script large downloads from NCBI?

Yes, within the published usage limits and with an API key. Batch requests with epost rather than looping one accession at a time, set a contact email for large jobs, and avoid rerunning downloads you already have on disk.

Exit mobile version