🎓 A1Learner
🔍
0 of 46 lessons completed

Bash Mapfile and Readarray

Mapfile reads lines into an array. Each line becomes one array item.

Read a file into an array

The printf line creates the file first. Mapfile reads it into colors, and the output shows the second colour and the count.

printf 'red\ngreen\nblue\n' > colors.txt
mapfile -t colors < colors.txt
echo "${colors[1]}"
echo "${#colors[@]}"

Count callback runs

The callback runs once per 2 lines. Six lines give three callback runs, and the count proves it.

printf 'one\ntwo\nthree\nfour\nfive\nsix\n' > numbers.txt
n=0
ticks() { ((n++)); }
mapfile -t -C ticks -c 2 lines < numbers.txt
echo "lines: ${#lines[@]}"
echo "callbacks: $n"

The last line without a newline

The file has no newline after three. Mapfile keeps all three lines, while the plain while loop keeps only two.

printf 'one\ntwo\nthree' > lines.txt
mapfile -t kept < lines.txt
while IFS= read -r line; do
  dropped+=("$line")
done < lines.txt
echo "${#kept[@]}"
echo "${kept[2]}"
echo "${#dropped[@]}"

Example

printf 'ada\ngrace\nlinus\nada\n' > names.txt
mapfile -t names < names.txt
echo "count: ${#names[@]}"
echo "first: ${names[0]}"
echo "last: ${names[-1]}"

Key points

  • mapfile -t: mapfile -t lines reads lines and drops the newline at each line end.
  • readarray: readarray is the same command under a second name.
  • Callback: mapfile -C ticks -c 2 runs ticks after every 2 lines read.
  • Callback count: a callback that adds one to a counter counts how many times it ran.
  • Input file: mapfile reads from a file with <, as in mapfile -t lines < names.txt.
  • Last line: mapfile keeps a last line that has no newline at its end.
  • While-read loop: a plain while read loop drops that last line, because read fails at the missing newline.

In this example, the printf line creates a file with four names. Mapfile reads the file into the names array. The echoes print the count, the first name, and the last name.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does the -t flag do in mapfile -t lines < names.txt?