grep,sed或awk来比较两个文件的内容

时间:2013-01-28 14:13:05

标签: bash sed awk grep line

我有以下问题,我正试图在bash中解决。我有两个不同的文件(file1,file2),包含如下信息列表:

HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

显示的字符串代表A SINGLE LINE。意思是如果我这样做:

grep "HWI-1KL104:145:C18ANACXX:5:1101:1168:2164" file1

我的输出是上面的字符串。 HWI-1KL104:145:C18ANACXX:5:1101:1168:2164 代表我行的ID

你必须想象数百万行这样的行(约8GB的txt文件)具有不同的ID

我要做的是:

  1. 搜索file2中存在的那些ID,这些ID存在于file2

  2. 将file2中的匹配行保存到一个只包含ID +以下信息的新文件中:

  3.   

    HWI-1KL104:145:C18ANACXX:5:1101:1196:2120   CCCCTTCTCCAGGGGACCANGTATGTTTCTCTTATGGTCCTCCTTGTTTACTAGCTTCTCTGGCAGTGAGATTGTAGGCTGGTAATTTTACTCNNTNNN CCCFFFFFHHHHJJJJJJJJ#4CDEEDCDDDDDC ######

    所以,丢弃由4 * 0 0 * * 0 0表示的东西(根据长度而不是内容而定。意味着可能是3 * 1 0 * * 0 1等等)

    所以我的file1代表了我想要找到并保存在file2中的ID的“引用”。

    我很难解释。我希望你明白我想做什么。

    我认为grep应该有用,但我不知道如何grep只是一行中的某些信息并与另一个文件进行比较。

4 个答案:

答案 0 :(得分:2)

假设文件只包含您想要的关键ID列表:

awk 'NR==FNR{ids[$0];next} $1 in ids{print $1,$10,$11}' file2 file1

答案 1 :(得分:1)

可以使用for循环

    outputfile="/tmp/something"
    file1=3; file2=4; 
    for ids in $(cat $file1|awk '{print $1}'); 
    do
          #echo working on $id**
          grep $ids $file2|awk '{print $3" "$4" "$5}' >> $outputfile
    done

上面是现在扩展的相同脚本,并且输出发送到文件,因此不是将脚本泵送到文件 - 您可以执行脚本并让它处理放置输出的位置。

当然你可以在大文件上运行它,它可能只需要一段时间才能开始并且可能需要一些时间才能完成,使用这种方法的问题是它工作且易于使用但可能不会像一些其他复杂的方法建议。

您可以启用处理ID行以获得更多详细信息

补充说明:

for filesfound in $(pattern=1101; grep $pattern 3*|awk -F":" '{print $1}'); do
 echo "found $filesfound"; 
 grep "newpattern" $filesfound; 
 done;

found 3
found 33

你可以进一步深入研究这样的初始grep:

 grep $pattern *|awk -F":" '{print "-- FILE: " $1 " --- ENTIRE_STRING: "$0}'
-- FILE: 3 --- ENTIRE_STRING: 3:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
-- FILE: 33 --- ENTIRE_STRING: 33:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

现在返回文件名|所有字符串然后查找模式并返回模式之后的所有内容 - 您可以通过在行尾添加更多awk语句来自定义它

pattern=1101; grep $pattern *|awk -F":" '{print $1"|"$0}'|awk -F"$pattern" '{print $2}'
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

答案 2 :(得分:0)

目前尚不清楚你想要哪个file2字段,但一个好的起点就是这样:

grep -Ff file1 file2 | tr -s ' ' | cut -d' ' -f1,9,10

或者如果file2是制表符分隔的:

grep -Ff file1 file2 | cut -f1,9,10

另外,您应该将这些数据保存在数据库中而不是文本文件中。

答案 3 :(得分:0)

4 * 0 0 * * 0 0始终采用相同的格式吗?如果在不知道各种可能情况的情况下如何回答这个问题,那就太难了。那个id怎么样,总是以相同的格式?

要使用grep(而不是整行)获取id,请使用-o。这只返回匹配的文本,而不是整行。

为了写入新文件并丢弃4 * 0 0 * * 0 0,您可以使用grep -v来查找字符串的反转。因此,如果您已经知道正在使用哪一行,grep -v '4 * 0 0 * * 0 0'

无论如何,这很大程度上取决于输入的确切格式以及各种边缘情况,但这可能会让你开始。