补充说明
readarray 是 Bash 4 起提供的内建命令,逐行读取标准输入或文件描述符,把每行作为一个数组元素保存。它与 mapfile 完全等价,只是名字不同;在脚本中比 while read 循环更简洁,也避免了管道子 shell 导致变量丢失的问题。
默认每行保留结尾换行符,使用 -t 可以去掉;-s 跳过开头若干行,-n 限制读取行数,-O 指定写入数组的起始下标。配合 -d '' 可以按 NUL 分隔读取,从而安全处理文件名中的空格和换行。
注意 readarray 是 Bash 专有功能,在 sh、dash 或 POSIX 模式下不可用,脚本首行应声明 #!/usr/bin/env bash。读取大文件时它会把全部内容放进内存,超大文件仍应考虑流式处理。
语法
readarray [选项] [数组名]
选项
-t:删除每行结尾的换行符-n <数量>:最多读取指定行数,0 表示全部-s <数量>:跳过开头指定行数-O <下标>:从指定数组下标开始赋值-d <字符>:使用指定分隔符代替换行(空字符串表示 NUL)-u <fd>:从指定文件描述符读取-C <命令>/-c <数量>:每读取若干行调用一次回调
实例
# 把文件每一行读入数组
readarray -t lines < /etc/hosts
printf '%s\n' "${lines[0]}"
# 跳过表头并只取前 10 行
readarray -t -s 1 -n 10 rows < data.csv
# 遍历数组
readarray -t users < <(cut -d: -f1 /etc/passwd)
for u in "${users[@]}"; do
echo "user: $u"
done
# 安全读取含空格/换行的文件名
readarray -d '' -t files < <(find . -maxdepth 1 -type f -print0)
printf '%s\n' "${files[@]}"
# 从指定下标开始写入已有数组
readarray -t -O 2 arr < <(printf 'a\nb\n')