There’s no map in bash…?

Niole Nelson
Niole Net
Published in
3 min readNov 22, 2021

--

Photo by Javardh on Unsplash

Why can’t you map over things in bash? When I first tried to usebash in order to do something “real”, I got super stuck because while arrays exist in bash you there is no map function to process them with.

Another thing I got super stuck on was returning values from functions, because there appeared to be no return either. When I eventually realized that the only way to get a value “out” of a function was to print it out, my brain exploded. Who would put such a feature in a programming language? The lack of map and return went against my entire dev existence up to that point, an existence where I cautiously avoided “side-effects” and where every function had to be “pure”.

IO all the way down…

It seems to be the case that in bash it’s IO all the way down. Yes, arrays do technically exist. The methods for operating on those arrays are decidedly lacking. I think that there might be a better approach here.

Reading lines from stdin

While map doesn’t exist, mapping still exists in spirit.

Lines of output is your new array. Functions like ls let you list files as lines of output. cat lets you output lines from files. Once the lines make it to stdin, transformations can be applied to the data in the same way.

read in combination with while lets you loop over these lines of “things”. Whether these things come from a file or from the output of another shell command, it doesn’t matter. read only cares about whether the data comes form stdin.

Say for example you want to make a bunch of API calls to get information about different stocks every day. In this case, the cleanest way to do this is to save a file with the ticker symbols on separate lines:

# stocks.txt
GOOG
AAPL
TSLA

Then the main script reads in the file contents line by line and hits the API for that stock and saves it in another file:

# get_stock_summary.sh
cat ./stock_list.txt | \
while read ticker
do
curl https://stock.api.com/$ticker >> ./stocks_2021-11-21.txt
done

Now all of your stock information is saved line by line to a file, which is labeled after today’s date.

Many programs meant for the command line read from stdin in order to work. This means that we can probably easily find something that lets us “map” over the data that we have gathered, transform it, and gather insights from it. jq is the example I will use here.

You could clean the data so that it is easier to read:

cat ./stocks_2021-11-21.txt | \
jq -s '.[] | [.symbol, .price]' >> stock_prices_2021-11-21.txt

You could gather all of the data from the last month for one of the symbols and get the average price:

ls | grep -E "stocks_2021-11-*.txt" | \
jq -s 'map(select(.symbol == "TSLA")) | .[].price' | \
jq 'add / length'

YNoA And sed

--

--