Bash循环中实现两个grep结果对应实例配对输出的方法
解决Bash中提取两类信息并一一配对输出的问题
我来帮你搞定这个配对输出的问题!你的原代码问题在于把单个文件里所有匹配到的样本名和reads数都堆在了同一行,没法实现一一对应的关联。咱们可以借助Bash的数组来分别存储每一类结果,再按索引配对输出,完美解决这个问题~
首先先修正你原代码里的小语法错误:两个$(...)命令都没闭合括号,这会导致脚本直接报错跑不起来。接下来是完整的修正方案:
#!/bin/bash echo "Utilized reads from ustacks output" > reads.txt str1="utilized reads:" str2="Parsing" for file in /home/desaixmg/novogene/stacks/sample01/conda_ustacks.o*; do # 将当前文件中匹配str2的所有样本名逐行读入数组 readarray -t samples < <(grep "$str2" "$file" | cut -d '/' -f 8) # 将当前文件中匹配str1的所有reads数逐行读入数组,xargs去除多余空格 readarray -t reads < <(grep "$str1" "$file" | cut -d ':' -f 3 | xargs) # 遍历数组索引,实现样本名与reads数的一一配对 for ((i=0; i<${#samples[@]}; i++)); do # 额外增加判断:避免样本数和reads数不匹配时输出空值 if [[ -n ${reads[i]} ]]; then echo "${samples[i]} ${reads[i]}" >> reads.txt else echo "Warning: No matching reads count for sample ${samples[i]} in file $file" >&2 fi done done
关键逻辑解释
readarray -t:把命令输出的每一行内容存入数组,-t参数会自动去掉每行末尾的换行符,保证数组元素干净。- 进程替换
< <(command):把grep+cut的输出当作临时文件,供readarray读取,这是Bash中实现“把命令输出导入数组”的常用技巧。 - 数组索引遍历:通过
${#samples[@]}获取数组长度,循环时用索引i关联samples和reads数组的对应元素,实现精准配对。 - 额外校验:如果某个文件里样本数和reads数不匹配(比如一个多一个少),脚本会输出警告到标准错误,避免生成无效的空行内容。
这样处理后,输出结果就会完全符合你的预期:每个样本名对应一行对应的reads数,清晰整齐。
内容的提问来源于stack exchange,提问作者Mgdesaix
相关产品推荐
相关产品推荐

