Introduction
Ever fetched data from a REST API only to get buried in nested JSON that's hard to scan quickly in the terminal? Whether you're debugging an endpoint, building a script, or just exploring data, you need a way to simplify and visualize it without firing up a full IDE or scripting language.
In this post, we'll pull country details from the REST Countries API, strip it down to essentials like flags, names, and populations, and pipe it straight into a clean ASCII table — all from the command line.
You'll end up with a pipeline that's fast, repeatable, and perfect for one-off queries or automation.
Install the packages
aux4 aux4 pkger install aux4/adapter aux4/2table
Fetching Country Data from the API
Start with the basics: grabbing the raw data. The REST Countries API gives you a massive JSON array with details on every country. We'll focus on key fields like codes, names, flags, capitals, languages, populations, timezones, and continents.
Run this to see the structure:
curl 'https://restcountries.com/v3.1/all?fields=cca3,name,flag,capital,languages,population,timezones,continents' \
--silent | head -c 1000
The output looks something like this:
[{"name":{"common":"Lithuania","official":"Republic of Lithuania","nativeName":{"lit":{"official":"Lietuvos Respublikos","common":"Lietuva"}}},"cca3":"LTU","capital":["Vilnius"],"languages":{"lit":"Lithuanian"},"flag":"🇱🇹","population":2794700,"timezones":["UTC+02:00"],"continents":["Europe"]}]
It's a lot — over 250 countries with nested objects everywhere. Languages are key-value pairs (e.g., {"lit": "Lithuanian"}), capitals and continents are arrays, and you just want the essentials.
Simplifying the JSON Response
Now, transform that raw mess into something usable. Create a countries.yaml config file to define exactly what to extract:
config:
countries:
format: json
mapping:
flag: $.flag
cca3: $.cca3
name: $.name.common
capital: $.capital[0]
continent: $.continents[0]
languages: $.languages
timezones: $.timezones
population: $.population
This grabs the flag emoji, country code, common name, first capital (handling multiples like South Africa's), first continent, the full languages object, timezones array, and population.
Pipe the API response through it:
curl 'https://restcountries.com/v3.1/all?fields=cca3,name,flag,capital,languages,population,timezones,continents' \
--silent \
| aux4 adapter map --configFile countries.yaml --config countries \
| head -c 2000
Here's a snippet of the cleaned-up JSON:
[
{
"flag": "🇱🇹",
"cca3": "LTU",
"name": "Lithuania",
"capital": "Vilnius",
"continent": "Europe",
"languages": {
"lit": "Lithuanian"
},
"timezones": "UTC+02:00",
"population": 2794700
},
{
"flag": "🇨🇱",
"cca3": "CHL",
"name": "Chile",
"capital": "Santiago",
"continent": "South America",
"languages": {
"spa": "Spanish"
},
"timezones": "UTC-06:00, UTC-04:00",
"population": 19116209
}
]
Notice how capitals and continents take the first item, timezones join into a string, and languages stay as an object for now (we'll handle display next).
For multi-language countries like Bolivia:
{
"cca3": "BOL",
"name": "Bolivia",
"capital": "Sucre",
"continent": "South America",
"languages": {
"aym": "Aymara",
"grn": "Guaraní",
"que": "Quechua",
"spa": "Spanish"
},
"timezones": "UTC-04:00"
}
And for multi-capital countries like South Africa, $.capital[0] picks the first one:
{
"cca3": "ZAF",
"name": "South Africa",
"capital": "Pretoria",
"continent": "Africa"
}
This keeps things simple — no more deep nesting, just the fields you need.
Rendering Data as an ASCII Table
With the JSON streamlined, pipe it to aux4 2table. Specify columns and let it handle alignment, even for objects and arrays:
curl 'https://restcountries.com/v3.1/all?fields=cca3,name,flag,capital,languages,population,timezones,continents' \
--silent \
| aux4 adapter map --configFile countries.yaml --config countries \
| aux4 2table flag,cca3,name,capital,continent,languages,timezones,population
The result is a neat ASCII table:
flag cca3 name capital continent languages timezones population
🇱🇹 LTU Lithuania Vilnius Europe lit: Lithuanian UTC+02:00 2794700
🇨🇱 CHL Chile Santiago South America spa: Spanish UTC-06:00, UTC-04:00 19116209
🇧🇯 BEN Benin Porto-Novo Africa fra: French UTC+01:00 12123198
🇫🇰 FLK Falkland Stanley South America eng: English UTC-04:00 2563
🇬🇪 GEO Georgia Tbilisi Asia kat: Georgian UTC+04:00 3714000
...
Languages show as lit: Lithuanian (key-value pairs flattened), timezones as comma-separated, and populations right-aligned.
For better labels, rename columns using the field:"Label" syntax:
curl 'https://restcountries.com/v3.1/all?fields=cca3,name,flag,capital,languages,population,timezones,continents' \
--silent \
| aux4 adapter map --configFile countries.yaml --config countries \
| aux4 2table flag,cca3:"Code",name:"Country",capital:"Capital",continent:"Region",languages:"Languages",timezones:"Time Zones",population:"Pop."
Output:
flag Code Country Capital Region Languages Time Zones Pop.
🇱🇹 LTU Lithuania Vilnius Europe lit: Lithuanian UTC+02:00 2794700
🇨🇱 CHL Chile Santiago South America spa: Spanish UTC-06:00, UTC-04:00 19116209
🇧🇯 BEN Benin Porto-Novo Africa fra: French UTC+01:00 12123198
...
Want Markdown output instead? Swap the format:
curl 'https://restcountries.com/v3.1/all?fields=cca3,name,flag,capital,languages,population,timezones,continents' \
--silent \
| aux4 adapter map --configFile countries.yaml --config countries \
| aux4 2table --format md flag,cca3,name,capital,continent,languages,timezones,population
| flag | cca3 | name | capital | continent | languages | timezones | population |
|---|---|---|---|---|---|---|---|
| 🇱🇹 | LTU | Lithuania | Vilnius | Europe | lit: Lithuanian | UTC+02:00 | 2794700 |
| 🇨🇱 | CHL | Chile | Santiago | South America | spa: Spanish | UTC-06:00, UTC-04:00 | 19116209 |
| 🇧🇯 | BEN | Benin | Porto-Novo | Africa | fra: French | UTC+01:00 | 12123198 |
Perfect for pasting into READMEs or pull request descriptions.
Conclusion
With two aux4 packages and a YAML config, you get a dead-simple CLI pipeline to fetch API data, transform it with precise mappings, and view it as a table — all without leaving your terminal.
The key idea: aux4/adapter handles the data shaping (flattening nested JSON, picking array elements, joining values), and aux4/2table handles the presentation. You can swap the API, change the mapping, or pipe the output into other tools.