如何在Bash的for循环中同步使用两个列表的对应变量?
如何在Bash中同时遍历两个列表的对应行执行命令?
我需要执行一条依赖两个变量的命令,但遇到了问题。想设置一个循环,让它从两个列表文件的第一行开始,逐行对应遍历完整个列表。我尝试了以下代码但未成功,感谢您的帮助。
错误代码示例:
#!/bin/bash i=$(cat list1.txt) j=$(cat list2.txt) for i in ${i}: for i in ${j} do python ggsashimi.py -b 1A_filtered.bam -c ${i} -g /gencode.v38.annotation.gtf -o ggsashimi/${j} samples -M 10 -C 3 -O 3 -A median --alpha 1 -F tiff -R 350 --base-size=16 --shrink --height=5 --width=18 --fix-y-scale done
问题分析
你的代码存在几个关键问题:
- 用
$(cat list.txt)读取整个文件内容到变量后,for循环会按空格/制表符/换行符拆分内容,而非按行遍历,行内有空格时会直接拆成多个元素。 - 两个
for循环写在一起的语法完全错误,Bash不支持这种写法。 - 重复使用变量名
i,会导致后一个循环覆盖前一个变量的值,无法同时获取两个列表的对应行数据。
正确解决方案
方法1:用paste+while read(推荐,适配含空格的行)
这种方法能保证两个文件的行严格对应,且支持行内包含空格的情况:
#!/bin/bash # 用paste合并两个文件的对应行,每行两个字段用制表符分隔 paste list1.txt list2.txt | while read -r i j; do python ggsashimi.py -b 1A_filtered.bam -c "${i}" -g /gencode.v38.annotation.gtf -o "ggsashimi/${j}" samples -M 10 -C 3 -O 3 -A median --alpha 1 -F tiff -R 350 --base-size=16 --shrink --height=5 --width=18 --fix-y-scale done
paste list1.txt list2.txt:把两个文件的对应行合并成一行,两个字段用制表符分隔。read -r i j:把每行的第一个字段赋值给i,第二个赋值给j,-r参数防止反斜杠被转义。- 变量用双引号包裹:避免行内有空格时被错误拆分。
方法2:用数组存储行内容(适合需要提前校验行数的场景)
如果需要先确认两个文件行数一致,可先把行内容存入数组,再按索引遍历:
#!/bin/bash # 把两个文件的行分别读进数组,-t参数去掉每行末尾的换行符 mapfile -t arr1 < list1.txt mapfile -t arr2 < list2.txt # 先检查两个文件行数是否一致 if [ "${#arr1[@]}" -ne "${#arr2[@]}" ]; then echo "错误:两个文件行数不一致" exit 1 fi # 按索引循环遍历对应元素 for (( idx=0; idx<"${#arr1[@]}"; idx++ )); do i="${arr1[idx]}" j="${arr2[idx]}" python ggsashimi.py -b 1A_filtered.bam -c "${i}" -g /gencode.v38.annotation.gtf -o "ggsashimi/${j}" samples -M 10 -C 3 -O 3 -A median --alpha 1 -F tiff -R 350 --base-size=16 --shrink --height=5 --width=18 --fix-y-scale done
内容的提问来源于stack exchange,提问作者Patchhr33
相关产品推荐
相关产品推荐

