Reading Files into Bash Arrays Using mapfile
When working with files in Bash, a common task is reading file content into an array. Traditionally, this is done using a while read loop. However, modern Bash provides a much simpler and more efficient built-in command called mapfile (also known as readarray).
mapfile can read an entire file into an array without complicated looping logic.
mapfile and readarray Are the Same
In Bash, mapfile and readarray are identical commands. They are simply two names for the same built-in function.
You can verify this using:
help mapfile
or
help readarray
Both will show the same documentation.
Sample File
Let’s begin with a sample file.
[root@oel01db Shell-Scripting]# cat sample-data.txt
My name is Mahesh.
I would like to do shell scripting.
I'm learning this from You Suck at Programming channel.
He is awesome.
[root@oel01db Shell-Scripting]#
Method 1: Reading a File Using a while read Loop
A traditional way to read a file into an array is by using a while read loop.
[root@oel01db Shell-Scripting]# cat on-read-using-while.sh
#!/usr/bin/env bash
myarray=()
# read file into array
while read -r line; do
myarray+=("$line")
done < sample-data.txt
# print array
printf '<%s>\n' "${myarray[@]}"
[root@oel01db Shell-Scripting]#
Explanation
myarray=()
Creates an empty indexed array.
while read -r line
Reads the file one line at a time.
The -r option is important because it prevents backslashes from being treated as escape characters. For example, \n will remain \n instead of being interpreted.
myarray+=("$line")
Appends the current line to the next available position in the array.
The quotes around "$line" are essential because they ensure that lines containing spaces are treated as a single array element.
Running the Script
[root@oel01db Shell-Scripting]# bash on-read-using-while.sh
<My name is Mahesh.>
<I would like to do shell scripting.>
<I'm learning this from You Suck at Programming channel.>
<He is awesome.>
[root@oel01db Shell-Scripting]#
This method works perfectly, but it requires more code.
Method 2: Using mapfile (Much Simpler)
If you are using a modern version of Bash, the same task can be done much more efficiently with a single command:
mapfile myarray < sample-data.txt
Example:
[root@oel01db Shell-Scripting]# cat 02-read-using-mapfile.sh
mapfile myarray < sample-data.txt
printf '<%s>\n' "${myarray[@]}"
[root@oel01db Shell-Scripting]#
Running it:
[root@oel01db Shell-Scripting]# bash 02-read-using-mapfile.sh
<My name is Mahesh.
>
<I would like to do shell scripting.
>
<I'm learning this from You Suck at Programming channel.
>
<He is awesome.
>
[root@oel01db Shell-Scripting]#
You may notice something interesting here.
The newline characters are preserved, which is why the output appears slightly different.
Removing Newline Characters with -t
To remove the trailing newline characters, use the -t option.
[root@oel01db Shell-Scripting]# cat 02-read-using-mapfile-trim.sh
mapfile -t myarray < sample-data.txt
printf '<%s>\n' "${myarray[@]}"
[root@oel01db Shell-Scripting]#
Running the script:
[root@oel01db Shell-Scripting]# bash 02-read-using-mapfile-trim.sh
<My name is Mahesh.>
<I would like to do shell scripting.>
<I'm learning this from You Suck at Programming channel.>
<He is awesome.>
[root@oel01db Shell-Scripting]#
Now the output matches the behavior of the while read loop.
Limiting the Number of Lines Read
mapfile reads the entire file into memory.
For very large files, this could be inefficient or even dangerous.
If you want to limit the number of lines read, you can use the -n option.
Example: read only the first 2 lines.
[root@oel01db Shell-Scripting]# cat 02-read-using-mapfile-limit.sh
mapfile -t -n 2 myarray < sample-data.txt
printf '<%s>\n' "${myarray[@]}"
[root@oel01db Shell-Scripting]#
Running the script:
[root@oel01db Shell-Scripting]# bash 02-read-using-mapfile-limit.sh
<My name is Mahesh.>
<I would like to do shell scripting.>
[root@oel01db Shell-Scripting]#
Only the first two lines are read into the array.
Summary
There are two common ways to read a file into a Bash array.
Using while read
-
Works in all Bash versions
-
More verbose
-
Reads line by line
Using mapfile
-
Much simpler
-
Faster and cleaner
-
Built specifically for reading lines into arrays
Useful options for mapfile:
| Option | Purpose |
|---|---|
-t | Remove trailing newline characters |
-n N | Read only N lines |
-s N | Skip the first N lines |
-O N | Start writing into the array at index N |
No comments:
Post a Comment