【问题标题】:Bash: tell if a file is included in anotherBash:判断一个文件是否包含在另一个文件中
【发布时间】:2013-03-24 23:37:30
【问题描述】:

我正在尝试比较两个文件的内容,并判断一个文件的内容是否完全包含在另一个文件中(意思是如果一个文件有三行,A、B 和 C,我可以在其中找到这三行吗?顺序,在第二个文件中)。我查看了diffgrep,但找不到相关选项(如果有的话)。

例子:

file1.txt   file2.txt  <= should return true (file2 is included in file1)
---------   ---------
abc         def
def         ghi
ghi
jkl    

file1.txt   file2.txt  <= should return false (file2 is not included in file1)
---------   ---------
abc         abc
def         ghi
ghi
jkl    

有什么想法吗?

【问题讨论】:

  • join(1) 可能有用。 linux.die.net/man/1/join
  • f1 和 f2 可以有空行吗?
  • 我想了一会儿comm,但它不会拒绝你的第二个例子。我的直觉是您不会找到完成这项工作的工具,但必须从适当的(脚本?)语言创建一个。我会使用 Perl,但 Python 或 Ruby 也应该没问题。

标签: bash diff file-comparison


【解决方案1】:

假设您的file2.txt 不包含对正则表达式具有特殊含义的字符,您可以使用:

grep "$(<file2.txt)" file1.txt

【讨论】:

  • 如果在我的第二个示例中存在部分匹配,则它不起作用(即使使用grep -F
【解决方案2】:

即使您的 file2.txt 包含特殊字符,这也应该有效:

cp file1.txt file_read.txt

while read -r a_line ; do
   first_line_found=$( fgrep -nx "${a_line}" file_read.txt 2>/dev/null | head -1 )
   if [ -z "$first_line_found" ]; 
   then 
        exit 1 # we couldn't find a_line in the file_read.txt
   else
        { echo "1,${first_line_found}d" ; echo "w" ; } | ed file_read.txt  #we delete up to line_found
   fi   
done < file2.txt
exit 0

(“exit 0”是为了“可读性”而存在的,因此只有当 fgrep 在 file1.txt 中找不到一行时,它才会以 1 退出。不需要)

(fgrep 是一个文字 grep,搜索一个字符串(不是正则表达式))

(我没有测试过上面的,这是一个普遍的想法。我希望它确实有效^^)

“-x”强制它与行完全匹配,即没有附加字符(即:“to”不能再匹配“toto”。添加-x时只有“toto”会匹配“toto”)

【讨论】:

  • grep -Fx 解决了正则表达式和部分行匹配的问题。其余的工作正常。
  • 我知道我查看了 fgrep (=grep -F) 的手册页并在您发表评论之前对其进行了编辑 ^^ 但是谢谢!
  • 我不确定它是如何工作的... grep 部分检查行是否匹配,循环部分对每一行进行检查,但是如何保留顺序?
  • 道歉:我根本不检查订单:(我会尝试编辑它。
  • 请尝试新的(我无法在这里检查,暂时无法访问外壳:我从头输入:/)
【解决方案3】:

使用here的答案

使用以下python函数:

def sublistExists(list1, list2):
    return ''.join(map(str, list2)) in ''.join(map(str, list1))

在行动:

In [35]: a=[i.strip() for i in open("f1")]
In [36]: b=[i.strip() for i in open("f2")]
In [37]: c=[i.strip() for i in open("f3")]

In [38]: a
Out[38]: ['abc', 'def', 'ghi', 'jkl']

In [39]: b
Out[39]: ['def', 'ghi']

In [40]: c
Out[40]: ['abc', 'ghi']

In [41]: sublistExists(a, b)
Out[41]: True

In [42]: sublistExists(a, c)
Out[42]: False

【讨论】:

    【解决方案4】:

    请尝试此 awk “单线” ^_^ 是否适用于您的真实文件。对于您问题中的示例文件,它有效:

    awk 'FNR==NR{a=a $0;next}{b=b $0}
    END{while(match(b,a,m)){
        if(m[0]==a) {print "included";exit}
        b=substr(b,RSTART+RLENGTH)
       }
        print "not included"
    }' file2 file1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多