- 此问题在此处已有答案**:
How to parse a CSV file in Bash?(6个答案)
2天前关闭。
假设我有输出/文件
1,a,info
2,b,inf
3,c,in
我想用read
运行while循环
while read r ; do
echo "$r";
# extract line to $arr as array separated by ','
# call some program (e.g. md5sum, echo ...) on one item of arr
done <<HEREDOC
1,a,info
2,b,inf
3,c,in
HEREDOC
我想使用readarray
和while
,但也欢迎引人注目的替代品。
有一种特定的方法可以让readarray
(mapfile
)正确地执行进程替换,但我总是忘记它。这是一个问答,所以解释一下会很好
4条答案
按热度按时间cunj1qz11#
因为
compelling alternatives are welcome too
并且假设您只是尝试一次填充arr
一行:或者,如果您还需要在单独的变量
r
中输入整行:但是无论如何要记住why-is-using-a-shell-loop-to-process-text-considered-bad-practice。
oalqel3c2#
readarray
(mapfile
)和read -a
消歧readarray
==mapfile
第一个:然后
而
read -a
:注:
只有在
$IFS
中找到的字符才被识别为单词分隔符。对-a
标志很有用!从拆分的字符串创建数组
要通过拆分字符串来创建数组,您可以:
一个三个三个一个
Oe使用
mapfile
,但由于此命令旨在处理整个 * 文件 *,因此语法有些违反直觉:或者,如果要避免使用fork(*
< <(printf...
*),则必须这样会快一点,但可读性不会更强...
对于您的样品:
一个9个1x一个10个1x一个11个1x
或者,如果您真的想使用
readarray
:一个12b1x一个13b1x
播放 *
callback
* 选项:(在最后一行添加了一些空格)
相同,带有
-u
标志:打开 * 文件描述符 *:
然后
一个17块一个18块一个
最后关闭 * 文件描述符 *:
关于bash
csv
模块有关
enable -f /path/to/csv csv
、RFC和限制的更多信息,请参阅my previous post about How to parse a CSV file in Bash?h6my8fg23#
如果可加载的内置
csv
可用/可接受,类似于:剧本。
help enable
对于
bash 5.2+
,config-top.h
中的可加载项有一个默认路径,该路径应该可以在编译时配置。tcbh2hod4#
解为
readarray -t -d, arr < <(printf "%s," "$r")
特殊部分是
< <(...)
,因为readarray ....找不到为什么首先需要重定向箭头然后需要进程替换的适当理由。
在tldp process-sub和SS64中都没有。
我最后的理解是,
<(...)
打开了一个命名管道,readarray正在等待它关闭,通过将其移动到<
后面的文件位置,bash将其作为文件输入处理,并(匿名地)通过管道传输到stdin。示例:
不管怎么说,这只是对我自己的提醒,因为我一直在忘记而readarray是我唯一真正需要这个的地方。
这个问题也得到了mostly here,here why the pipe isn't working和某种程度上here的回答,但它们很难找到,推理也很难理解。
例如
shopt -s lastpipe
解决方案一开始并不清楚,但它证明在bash中所有管道元素通常不在主shell中执行,因此状态更改对整个程序没有影响.这个命令更改行为以使最后一个管道元素在主shell中执行(除了在交互式shell中)lastpipe的一个替代方案是在子 shell 中执行所有活动: