Mapfile 不删除尾随换行符

Mapfile 不删除尾随换行符
  • 示例数据:制表符分隔的 tsv 文件
a.1.58  fadado/CSV  https://github.com/fadado/CSV
a.1.63  jehiah/json2csv https://github.com/jehiah/json2csv
a.1.80  stedolan/jq https://github.com/stedolan/jq/issues/370
  • 以下使用 fzf 选择一条记录,并将第二列和第三列存储到数组链接:
mapfile -d $'\t' -t Link < <(awk 'BEGIN{FS="\t"; OFS="\t"} {print $2,$3}' "${SessionP}" | fzf)

问题

在上面的命令中,我使用了-tmapfile 选项,但echo "${Link[1]}"打印了一个尾随新行!

为什么没有被淘汰呢?


参考

答案1

检查本地文档,而不是在网络上其他地方找到的文档。在交互式bashshell 会话中,键入或在手册 ( )中help mapfile查找文档。根据您的 版本,文档可能与网上找到的内容有所不同。mapfilebashman bashbash

在我的系统上,bash5.1.8help mapfile记录了-t如下选项mapfile

-t 从读取的每行中删除尾随的 DELIM(默认换行符)

设置DELIM-d

-d delim 使用 DELIM 终止行,而不是换行符

这意味着当使用-d $'\t' -twith时mapfile,它将删除尾随制表符,如果有的话,不是尾随换行符。

该shell自 4.4 版本以来bash已有。mapfile -d该选项的介绍已记录在案像这样:

内置函数mapfile现在可以-d选择使用任意字符作为记录分隔符,以及-t删除 提供的分隔符的选项-d

要在打印最后一个元素时从数据中删除尾随换行符,请"${Link[1]%$'\n'}"在输出元素时使用。如果最后一个字符是换行符,这将从元素中删除最后一个换行符。

答案2

如果输入数据(在awk和 之后fzf)类似于

fadado/CSV<tab>https://github.com/fadado/CSV<nl>

如果您想要将这两个字段分开,那么mapfile不一定是最好的工具。相反,您可以使用read -a读取数组或read使用两个变量名称:

这会将两个字段读取到${arr[0]}${arr[1]}

IFS=$'\t' read -r -a arr < ...

或者

IFS=$'\t' read -r x y < ...

例如(为了示例而跳过进程替换):

IFS=$'\t' read -r -a arr <<< $'fadado/CSV\thttps://github.com/fadado/CSV\n'
printf "'%s' '%s'\n" "${arr[0]}" "${arr[1]}"

印刷

'fadado/CSV' 'https://github.com/fadado/CSV'

相关内容