This is an old revision of the document!
The mapfile builtin command
incomplete
Synopsis
mapfile [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY]
readarray [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY]
Description
The mapfile
builtin command is used to assign lines of standard input (e.g. from a file with redirection) to an array named by ARRAY
, each line in a separate element. If no array is named, the default array name is MAPFILE
. The target array must be a "normal" integer indexed array.
The mapfile
builtin returns success (0) unless an invalid option is given or the given array ARRAY
is set readonly.
This builtin is also accessible as readarray
.
Option | Description |
---|---|
-c QUANTUM | Specifies the number of lines that have to be read between every call to the callback specified with -C . The default QUANTUM is 5000 |
-C CALLBACK | Specifies a callback. The string CALLBACK can be any shell code, the index of the array that will be assigned, and the line is appended at evaluation time. |
-n COUNT | Reads at most COUNT lines, then terminates. If COUNT is 0, then all lines are read (default). |
-O ORIGIN | Starts populating the given array ARRAY at the index ORIGIN rather than clearing it and starting at index 0. |
-s COUNT | Discards the first COUNT lines read. |
-t | Remove any trailing newline from a line read, before it is assigned to an array element. |
-u FD | Read from filedescriptor FD rather than standard input. |
The callback function, if defined, is called before the assignment of the array element, thus you can only use it as a kind of progress bar,
mapfile -n 11 -c 2 -C echo <file 0 #as of 4.0rc1 there is a bug 2 4 8if you want to get rid of the counter, you can use tricks like
$ mapfile -n 11 -c 2 -C 'printf . \#' <file .....if you want to use it elsewhere, you can use a function:
$ foo () { echo "|$1|"; }; mapfile -n 11 -c 2 -C 'foo' <file |2| |4| etc..
Rant
mapfile
doesn't introduce a new feature. All mapfile
provides can be done with a small while read
loop or similar, too. In fact, mapfile
could be easily implemented as shell function. Personally, I don't understand why something like that is implemented.
Note mapfile is significantly faster than a read loop. It's one of those features I suspect was added for no other reason than performance. It may also have been added for completeness as Bash's file I/O is analogous to those of other languages. Compare with methods on Python file objects: read → f.readline(); mapfile → f.readlines(); read -N → f.read(). The only thing still missing is the traditional seek() functionality. Some shells have this, such as ksh93's <#(()) redirection operator.
Bugs
As of RC1, there still are some implementation bugs, for example mapfile
filling the readline history buffer with calls to the CALLBACK
.
* Update(1): This is still present at Bash 4.1 alpha release, I wonder if this is considered a bug. * Update(2): Might be "fixed" (eliminated) in 4.1 beta, thanks Chet * Update(3): Fixed according to Changelog in 4.1 beta, thanks
Examples
Portability considerations
mapfile
/readarray
is not portable.
Discussion