mapfile – 標準入力を配列に読み込む(bash組み込み・別名 readarray)

グロブ/パターン
スポンサーリンク

mapfile は標準入力(またはFD)から読み取った各レコードを配列に格納する Bash の組み込みコマンドです(別名:readarray)。デリミタ(既定は改行)や読み取り件数、スキップ件数、コールバックなどを細かく制御できます。
実務では、コマンド出力やファイルの各行を安全に配列化して後段処理で扱うときに使います。

構文(Syntax)

# bash 4+
mapfile [-d DELIM] [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-r]
        [-C CALLBACK [-c QUANTUM]] ARRAY_NAME

# 同義コマンド
readarray … ARRAY_NAME
  • ARRAY_NAMEインデックス配列名。各レコードが ARRAY_NAME[0], [1], ... に入ります。
  • 既定のデリミタは改行(\n)。-t を付けると末尾のデリミタを除去します。

主なオプション一覧

オプション説明使用例
-t末尾のデリミタ(改行など)を取り除いて格納mapfile -t lines < file.txt
-d DELIMレコード区切り文字を指定(1文字)。NULは -d $'\0'mapfile -d $'\0' -t items < list.nul
-n COUNT最大 COUNT 件だけ読み込みmapfile -n 5 -t top5 < file.txt
-s COUNT先頭から COUNT 件を読み飛ばすmapfile -s 1 -t body < file.csv
-O ORIGIN配列の書き込み開始インデックス(追記に便利)mapfile -O "${#arr[@]}" -t arr < more.txt
-u FD指定FDから読む(既定は stdinexec 3< file; mapfile -u 3 -t lines
-rバックスラッシュによるエスケープを無効化(そのまま読み込む)mapfile -r -t raw < file
-C CALLBACKQUANTUM 行ごとに CALLBACK 関数を呼ぶmapfile -C progress -c 100 -t lines < big.txt
-c QUANTUM-C の呼び出し間隔(デフォルトは 5000)-C cb -c 1000

実行例

ファイルの各行を配列に読み込む(基本)

説明:改行を除いた行配列を作ります。
コマンド

mapfile -t lines < /etc/hosts
printf '%s\n' "${lines[@]}" | head

出力例/etc/hosts の先頭行から表示。

プロセス置換でコマンド出力を配列化

説明git ls-files の結果を配列に格納します。
コマンド

mapfile -t tracked < <(git ls-files)
echo "計: ${#tracked[@]} 件"

先頭1行をヘッダとしてスキップして読む

説明:CSVの1行目(ヘッダ)を飛ばして読み込みます。
コマンド

mapfile -s 1 -t rows < data.csv
echo "データ行: ${#rows[@]}"

NUL区切り入力を安全に読む(ファイル名に改行があってもOK)

説明find -print0 の出力を NUL 区切りで配列化。
コマンド

mapfile -d $'\0' -t files < <(find . -type f -print0)
printf '%q\n' "${files[@]}" | head

大きな入力で進捗表示(コールバック)

説明:100行ごとに進捗を表示するコールバックを使います。
コマンド

progress() { printf '\r... %s 行読み込み' "$1"; }
mapfile -C progress -c 100 -t big < biglist.txt
echo -e "\n完了: ${#big[@]} 行"

エラー例:存在しないFDを指定

説明:未オープンのFDを -u に渡すと失敗します。
コマンド

mapfile -u 9 -t lines
echo $?

出力例(例)

bash: mapfile: -u: invalid file descriptor specification
1

関連コマンド

  • read:1レコードずつ読み込む基本コマンド(-r, -d 等)。
  • printf:配列内容の整形出力に。
  • xargs -0 / find -print0:NUL 区切りでの受け渡し。
  • while IFS= read -r line; do ...; done:逐次処理の定番パターン。

備考

  • Bash限定mapfile/readarrayBash専用です(POSIX shdash にはありません)。
  • デリミタ-d1文字のみ有効。NUL は -d $'\0' を使用してください。-t を併用すると末尾デリミタを落とせます。
  • 改行・バックスラッシュ:改行を保持したい場合は -t を付けないこと。バックスラッシュをそのまま残したい場合は -r を付けます。
  • 巨大入力:配列に全読み込みするためメモリを消費します。行ごと処理で十分な場合は while read ループの方が安全です。
  • コールバック-C name -c N のコールバックには「読込済み行数(1始まり)」が $1 で渡されます。副作用の強い処理は避け、軽量に保つのが無難です。

参考

スポンサーリンク
Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント