【问题标题】:Comparing 2 files with a for loop in bash将 2 个文件与 bash 中的 for 循环进行比较
【发布时间】:2018-08-18 19:32:05
【问题描述】:

我正在尝试比较 2 个文件中的值。对于 Summits3.txt 中的每一行,我想将第 1 列中的值定义为“Chr”,然后在generef.txt 中找到我在第 2 列中具有“Chr”值的行。 然后我想从generef.txt输出一些关于该行的信息到out.txt,然后重复直到结束。 我正在使用以下脚本:

#!/bin/bash
IFS=$'\n'
for i in $(cat Summits3.txt)
do
Chr=$(echo "$i" | awk '{print $1}')   
awk -v var="$Chr" '{
if ($2==""'${Chr}'"")
print $2, $3
}' generef.txt > out.txt
done

它“有效”,但它只比较 Summits3.txt 最后一行的值。它似乎没有循环通过 awk 位。

如果可以的话,请帮忙!

【问题讨论】:

  • 欢迎来到 Stack Overflow,请在您的帖子中也将示例 Input_file 和预期的输出示例文件发布在代码标签中。

标签: bash variables for-loop awk


【解决方案1】:

我想你可能正在寻找这样的东西:

awk 'FNR == NR {a[$1]; next} $2 in a {print $2, $3}' Summits3.txt generef.txt > out.txt

基本上,您将第一个文件中的第一列读入数组(数组索引是您的 chr,值是空字符),然后对于第二个文件,仅打印第二列在数组索引集中的行。 FNR 当前正在处理的文件中的行号,NR 到目前为止所有已处理行的行号。这是我用来从一个文件中提取另一个文件中存在的基因或变异的通用查找命令。

在您上面的代码中,它应该附加到 out.txt:>> out.txt。但是您必须确保在每次运行时重新设置 out.txt。

【讨论】:

  • 这是传统、简单且几乎总是正确的解决方案。如果 OP 费心搜索“加入染色体列”,他们会在这个网站上找到数十或数百种此解决方案的变体。
【解决方案2】:

除了在循环中使用外部脚本(这很昂贵)之外,我们看到的第一件事就是您将输出从循环内部重定向到文件。每次都会重新创建输出文件,因此请更改 inte append (>>) 或更好地将重定向移到循环之外。
当你想使用循环时,试试这个

while read -r Chr other; do
   cut -d" " -f2,3 generef.txt | grep -E "^${Chr} "
done < Summits3.txt > out.txt

如果您想避免循环(大型输入文件需要),可以使用awk 或一些组合命令。
第一个解决方案可能会失败:

grep -f <(cut -d" " -f1 Summits3.txt) <(cut -d" " -f2,3 generef.txt)

您只想要完整字段 Chr 的匹配项,因此从第一个位置开始直到一个空格(我假设那是 field-sep)。

grep -f <(cut -d" " -f1 Summits3.txt| sed 's/.*/^& /') <(cut -d" " -f2,3 generef.txt)

【讨论】:

    猜你喜欢
    • 2013-08-10
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多