如何在bash中比较两个文本文件的行和列的值?

时间:2014-06-18 20:55:06

标签: awk

我有两个文本文件,我想根据它们的行和列比较它们的对应值。通过比较,我的意思是检查值是否相等,如果值相同则检查echo。以下是文件:

FILE1.TXT

Name  Col1  Col2  Col3  
-----------------------
row1  1     4     7        
row2  2     5     8         
row3  3     6     9   

FILE2.TXT

Name  Col1  Col2  Col3  
-----------------------
row2  1     4     11        
row1  2     5     12           

以下是限制因素:

  • 仅比较存在的行(即:因为row3存在于file1.txt中但不存在于file2.txt中,因此不需要进行比较)
  • 比较必须一次完成一行一列。
  • 必须使用awk
  • 文件
  • 中的行可能不按顺序排列

我在考虑这样的事情:

awk 'NR>2
    for (i=2;i<NR;i++)              #for each row of file1.txt
    {     
        for(j=1;i<NF;j++)           #for each column of file1.txt
        {
             // check if row and column of file1.txt is equal to row and column of file2.txt
        } 
    }

' file1.txt file2.txt

我是bash的初学者,请原谅我的所有错误。这样的事情可能吗?另外,您如何比较两个不同文本文件的值?谢谢。如果需要更多解释,请告诉我。

1 个答案:

答案 0 :(得分:2)

显然这是一个家庭作业问题,所以我会给你一些提示。你必须有一本awk书来阅读你可以在哪里学到详细信息。

您尝试使用NR的方式不正确。它不是记录总数,而是当前记录的数量。

请记住,awk脚本是一个规则列表,每个规则的格式为pattern {actions}。所以你的程序应尽可能采用这种形式。 awk的基本机制是读取记录,依次针对每个规则的模式测试它,如果它匹配模式然后执行相关的操作,当它到达规则的末尾时,继续下一个记录。它是“数据驱动的”,例如,与C或Java等语言非常不同。

您可以使用如下初始规则跳过这两个文件的前两行:

FNR < 3 { next }  # if file record number < 3, go to next record

有一种惯用的方式来处理两个文件。 NR == FNR仅在第一个文件中为真,因为NR(记录号)在文件之间保持递增,而FNR(文件记录号)在文件之间重置。所以你可以这样做:

NR == FNR {
    # Only the first file's records will be processed here

    next  # go on to the next record
}

在处理第一个文件时,您需要使用关联数组来保存记录,由第一个字段键入。

最终规则将只处理第二个文件,测试第一个字段是否是关联数组中的键,如果是,则比较其他字段以查看它们是否匹配。

所以你的程序可能有这个结构:

FNR < 3 { next }  # if file record number < 3, go to next record

NR == FNR {
    # Only the first file's records will be processed here

    # Save info in an associative array.
    aa[$1] = ...

    next  # go on to the next record
}

# If a rule has no pattern, it matches every record
{
    # Only the second file's records will be processed here

    if ($1 in aa) {
        # compare fields
    }
}