如何仅用Bash变量拼接两列数据并循环遍历(无需临时文件)
问题描述
用户有两个包含两列数据的Bash变量(示例对应tmp文件里的foo和bar行),希望将它们拼接为更长的列后遍历每行,把每列内容读入临时变量。示例中tmp文件由以下代码生成:
for i in `seq 1 10`; do echo foo $i; done > tmp for i in `seq 1 10`; do echo bar $i; done >> tmp for i in `seq 1 10`; do echo baz $i; done >> tmp
原实现依赖多个临时文件:
grep foo tmp > file1 grep bar tmp > file2 cat file1 file2 > file_tmp while read word number do if [ $word = "foo" ] then echo word $word number $number fi done < file_tmp rm file1 file2 file_tmp
需求是不生成任何临时文件完成上述逻辑。
无临时文件的实现方案
方法1:命令组合+管道直接传递
直接将grep foo和grep bar的输出合并后,通过管道传给while循环,完全跳过临时文件:
{ grep foo tmp; grep bar tmp; } | while read word number; do if [ "$word" = "foo" ]; then echo word $word number $number fi done
- 大括号
{ ...; }将两个grep命令组合成一个整体,它们的标准输出会被合并后统一传入管道 - 所有操作在内存中完成,无需创建任何中间文件
方法2:进程替换(解决子shell变量作用域问题)
如果需要让while循环内的变量在外部可见,可使用Bash进程替换语法,避免管道创建子shell导致的变量隔离:
while read word number; do if [ "$word" = "foo" ]; then echo word $word number $number # 示例:将结果存入外部可访问的数组 results+=("$word $number") fi done < <(grep foo tmp; grep bar tmp) # 循环外可直接访问results数组 echo "外部获取的结果:${results[@]}"
< <(...)会将括号内命令的输出作为while循环的输入,且不会创建子shell,循环内的变量在外部依然有效
方法3:多模式匹配简化写法
如果不需要严格按foo在前、bar在后的顺序处理,可直接用grep匹配多个模式:
grep -E 'foo|bar' tmp | while read word number; do if [ "$word" = "foo" ]; then echo word $word number $number fi done
内容的提问来源于stack exchange,提问作者Pythonist
相关产品推荐
相关产品推荐

