1. 命令简介
mapfile(别名为 readarray)是 Bash shell 的内建命令。它的核心功能是从标准输入或指定的文件描述符中逐行读取数据,并将每一行内容赋值给一个数组元素。 这是将文本数据流高效转换为结构化数组的理想工具,特别适用于需要按行处理文件或命令输出的场景。
2. 语法格式
bash
运行
mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]3. 常用选项及说明
表格
| 选项 | 参数 | 说明 |
|---|---|---|
| -d | delim | 指定行分隔符,默认是换行符(\n)。 |
| -n | count | 最多读取 count 行。如果 count 为 0,则读取所有行。 |
| -O | origin | 从数组下标 origin 处开始赋值,默认为 0。 |
| -s | count | 跳过输入的前 count 行,不予读取。 |
| -t | 无 | 移除每行末尾的分隔符(例如默认的换行符)。 |
| -u | fd | 从文件描述符 fd 读取数据,而非标准输入。 |
| -C | callback | 每读取 quantum 行后,执行一次 callback 语句。 |
| -c | quantum | 与 -C 联用,指定触发回调的行数间隔,默认为 5000。 |
参数说明
array(可选):目标数组的名称。如果省略,则默认使用 MAPFILE 数组。
返回值
- 成功:返回 0。
- 失败:返回非零值(例如使用了非法选项、目标数组为只读或非下标数组)。
4. 示例用法
4.1 基本读取
bash
运行
# 从文件读取到默认数组 MAPFILE mapfile < file.txt # 从管道读取到自定义数组 cat file.txt | mapfile myarray # 从文件描述符 3 读取(需提前打开) exec 3< file.txt mapfile -u 3 myarray exec 3<&-4.2 控制读取范围
bash
运行
# 只读取文件的前 10 行 mapfile -n 10 < file.txt myarray # 跳过文件的前 5 行 mapfile -s 5 < file.txt myarray # 从数组下标 2 的位置开始赋值(不清空数组原有内容) mapfile -O 2 < file.txt myarray4.3 自定义分隔符与修剪
bash
运行
# 使用 Tab 字符作为分隔符 mapfile -d $'\t' < data.tsv myarray # 移除行尾的换行符(使数组元素更“干净”) mapfile -t < file.txt myarray4.4 使用回调函数
bash
运行
# 每读取 3 行,输出一次进度信息 mapfile -C "echo 'Processed lines up to index:'" -c 3 < file.txt myarray # 回调函数接收两个参数:下一个要赋值的下标、当前读取的行内容 mapfile -C "echo 'Index \$1, line content:'" -c 2 < file.txt myarray4.5 数组的遍历与使用
bash
运行
# 读取文件到数组,并移除换行符 mapfile -t < file.txt lines # 遍历数组(按索引) for i in "${!lines[@]}"; do echo "$i: ${lines[$i]}" done5. 注意事项
- 内建命令:mapfile 是 Bash 内建命令。查看完整帮助请使用
help mapfile或help readarray。 - 数组清空行为:默认情况下,mapfile 会清空目标数组,除非使用了 -O 选项并指定了起始位置。
- 分隔符处理:使用 -d 指定的分隔符本身不会包含在数组元素中。-t 选项用于进一步移除这个分隔符。
- 性能考虑:处理超大文件时,可结合 -C 和 -c 选项进行分批处理,以监控进度或控制内存。回调函数应尽量高效。
- 错误处理:确保目标数组可写,使用 -u 选项时文件描述符必须已正确打开。
- 兼容性:该命令在 Bash 4.0 及以上版本中可用。编写可移植脚本时,应考虑备选方案。
兼容性备选方案
使用 while read 循环可以实现类似功能,兼容性更广:
bash
运行
myarray=() while IFS= read -r line; do myarray+=("$line") done < file.txt