This is an old revision of the document!


The mapfile builtin command

:V4: FIXME 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

This builtin is also accessible using the command name readarray.

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.

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: