bash从两个文件中获取信息

时间:2017-03-07 09:23:34

标签: bash shell awk sed

我有file1:

NM_000014   A2M
NM_000015   NAT2
NM_000016   ACADM
NM_000017   ACADS
NM_000018   ACADVL
NM_000019   ACAT1
NM_000020   ACVRL1
NM_000021   PSEN1
NM_000022   ADA

和file2:

NM_000019   
NM_000020   
NM_000020
NM_12345

我需要从我的file1获取信息并将其放到file2中 - 所以创建file3:

NM_000019   ACAT1
NM_000020   ACVRL1
NM_000020   ACVRL1
NM_12345    NO

注意 - 我无法更改原始排序顺序(因此不要使用comm和diff)。我在file2中有重复行 - 我需要保持(wc -l file2 == wc -l file3)。如果没有匹配项 - 请打印NO

我有大约70K行,我不需要最快的解决方案。 我的代码只能比较和打印相同的结果。

代码:

#!/bin/bash

while read -r c; do


grep $c file1  | uniq 

done < file2 > file3

4 个答案:

答案 0 :(得分:3)

使用awk:

$ awk 'NR==FNR{a[$1]=$2;next} {print ($1 in a?$1 OFS a[$1]:$1 OFS "NO")}' file1 file2
NM_000019 ACAT1
NM_000020 ACVRL1
NM_000020 ACVRL1
NM_12345 NO

说明:

NR==FNR{                                      # process the first file
    a[$1]=$2                                  # hash records to a, $1 as key
    next                                      # skip to next record
} 
{                                             # process the second file
    print ($1 in a?$1 OFS a[$1]:$1 OFS "NO")  # print hashed value if found or NO

#   if($1 in a)                               # another way of saying above
#       print $1, a[$1] 
#   else 
#       print $1, "NO"
}

答案 1 :(得分:1)

所以基本上你有一个带有模式的文件,第二个要用这些模式搜索的文件:

#!/bin/bash

for PATTERN in $(cat $2); do
    TMP=$(egrep $PATTERN $1)
    if [ ! -z "$TMP" ]; then
        echo "$TMP" 
    else
        echo "$PATTERN NO"
    fi
done

并快速测试:

$ bash filter.sh file1 file2
NM_000019   ACAT1
NM_000020   ACVRL1
NM_000020   ACVRL1
NM_12345 NO

答案 2 :(得分:1)

尝试将此if句添加到您的代码中:

if ! grep -q $i fileone ; then
  echo -e $i "   NO"
fi

例如:

#!/bin/bash
while read -r c; do grep $c fileone  | uniq; done < filetwo
for i in $(cat filetwo)
do
  if ! grep -q $i fileone ; then
    echo -e $i "   NO"
  fi
done

如果file1中没有与file2行匹配的情况,它将打印NO。

答案 3 :(得分:0)

尝试粘贴命令。这比awk更不高贵。我更喜欢awk但是粘贴命令可以帮助你。

粘贴file1 file2 file3 ... etc ..fileN

您可以照常将命令输出重定向到文件。

粘贴file1 file2 file3 ... etc ..fileN&gt; fileN + 1(或其他)

这是逐行读取文件并按顺序顺序分段输出。

那就是它。它不是很优雅,但有时​​它会非常有用,直到你找到一种不同的方式来获得你想要的结果。

希望有所帮助