需要在linux中使用文件行中的一些模式来区分两个文本文件

时间:2016-04-12 12:20:30

标签: shell scripting

文件A包含

Test-1.2-3
Test1-2.2-3
Test2-4.2-3

文件B包含

Test1

预期输出应为

Test-1.2-3
Test2-4.2-3

diff A B没有按预期工作 如果有任何解决方案,请告诉我。

2 个答案:

答案 0 :(得分:2)

使用grep

grep -vf B A

  -f FILE, --file=FILE
          Obtain patterns  from  FILE,  one  per  line.   The  empty  file
          contains zero patterns, and therefore matches nothing.

  -v, --invert-match
          Invert the sense of matching, to select non-matching lines.

修改

如果您希望更精确地匹配"单词"您可以选择使用-w选项。只有你的例子似乎是你的情况,因为你的比赛后面是' - '。正如DevSolar指出的那样,您可能还希望使用-F选项来防止文件B中的输入模式被解释为正则表达式。

grep -vFwf B A

  -w, --word-regexp
          Select only those  lines  containing  matches  that  form  whole
          words.   The  test is that the matching substring must either be
          at the  beginning  of  the  line,  or  preceded  by  a  non-word
          constituent  character.  Similarly, it must be either at the end
          of the line or followed by  a  non-word  constituent  character.
          Word-constituent   characters   are  letters,  digits,  and  the
          underscore.
  -F, --fixed-strings
          Interpret PATTERN as a list of fixed strings (rather than regular
          expressions), separated by newlines, any of which is to be matched.

答案 1 :(得分:1)

补充Julien Lopez's helpful answer

如果您想确保文件B中的行仅在文件A 处匹配,您可以^添加到文件B 中的每一行,使用sed

grep -vf <(sed 's/^/^/' fileB) fileA

grep,默认情况下将其搜索字符串解释为BREs (basic regular expressions),然后将^解释为行首锚点。

如果文件B中的行可能包含正则表达式元字符的字符(例如^*?,...),但应该被视为文字,你必须首先逃避

grep -vf <(sed 's/[^^]/[&]/g; s/\^/\\^/g; s/^/^/' fileB) fileA

在我this answerprocess substitution中可以找到对这种看起来很严峻 - 但通用性强 - sed命令的解释。

注意:

  • 假设bashkshzsh因使用<(...)http://bizcoder.com/posting-raw-json-to-web-api而产生sed行为好像它是通过文件提供的。
  • sed命令s/^/^/看起来无法做任何事情,但是正则表达式部分中的第一个^是行首锚 [1] 而第二个^,在调用的替换部分,是一个文字放置在行的开头(稍后它将被解释为行首)在grep)的背景下锚定。

[1]严格地说,sed它是模式空间的开始,因为可以用{{一次读取多行“ 1}},在这种情况下sed指的是模式空间(输入缓冲区)作为一个整体的开头,而不是单个行。