This is an old revision of the document!


The mapfile builtin

:V4: FIXME incomplete

Synopsis

mapfile [-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
8
if 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.

See also

Discussion

Enter your comment. Wiki syntax is allowed: