如何在Bash中将多行输出拆分为单个命令参数?
问题:将命令输出的每行作为单独参数传递(一行命令实现)
假设某程序some_program的输出为多行文本:
$ some_program line 1 line 2
现在需要把该输出的每一行作为单个参数传递给count_arguments命令,但以下两种常用方式都无法满足需求:
- 无引号的命令替换:
这种方式会把换行和空格都当作分隔符,最终拆分出4个参数,不符合要求。$ count_arguments $(some_program) 4 - 带双引号的命令替换:
这种方式会把所有输出内容合并成单个参数,最终仅得到1个参数,也不符合要求。$ count_arguments "$(some_program)" 1
已知可以通过中间步骤将输出读入数组,再用"${arr[@]}"传递参数,但希望找到一行命令的解决方案,是否可行?
可行的一行命令方案
方案1:用readarray(Bash 4.0及以上版本)
直接在一行内完成数组赋值并传递参数:
readarray -t arr < <(some_program) && count_arguments "${arr[@]}"
-t参数会自动去掉每行末尾的换行符,避免参数携带多余的换行。< <(some_program)是进程替换语法,把some_program的输出直接作为readarray的输入。
方案2:修改IFS配合命令替换(兼容旧版Bash)
临时将字段分隔符IFS设置为仅换行,让命令替换只按行拆分:
IFS=$'\n' count_arguments $(some_program)
- 这里的
IFS修改只在当前命令执行时生效,不会影响后续的Shell环境。 - 如果输出行包含空格但不想被拆分,或者需要避免通配符扩展(比如行内有
*),可以加上set -f:
IFS=$'\n' set -f; count_arguments $(some_program); set +f
方案3:用xargs(跨Shell通用)
如果count_arguments支持通过xargs接收参数,可以用换行作为分隔符传递:
some_program | xargs -d $'\n' count_arguments
-d $'\n'指定换行符为参数分隔符,确保每行作为单独参数。- 若你的系统
xargs不支持-d参数(比如BSD系统),可以用tr把换行转成null字符,配合xargs -0:
some_program | tr '\n' '\0' | xargs -0 count_arguments
内容的提问来源于stack exchange,提问作者nadapez
相关产品推荐
相关产品推荐

