【问题标题】:extract different lines from files using Bash使用 Bash 从文件中提取不同的行
【发布时间】:2013-11-18 11:53:47
【问题描述】:

我有两个文件,我使用“comm -23 file1 file2”命令来提取与另一个文件不同的行。

我还需要提取不同行但还保留字符串“line_$NR”的东西。 例子: 文件1:

line_1: This is line0
line_2: This is line1
line_3: This is line2
line_4: This is line3

文件2:

line_1: This is line1
line_2: This is line2
line_3: This is line3

我需要这个输出: 差异文件1文件2:

line_1: This is line0.

总之,我需要提取差异,就好像文件在开始时没有 line_$NR 但是当我打印结果时我还需要打印 line_$NR。

【问题讨论】:

  • 我想要文件之间的某种差异,但不比较 line_NR,只打印 line_NR。不知道comm是否合适。
  • 您的diff 版本可能具有生成comm 类似并排输出的选项。

标签: bash comm


【解决方案1】:

尝试使用awk

awk -F: 'NR==FNR {a[$2]; next} !($2 in a)' file2 file1

输出:

line_1: This is line0

简短说明

awk -F: '             # Set filed separator as ':'. $1 contains line_<n> and $2 contains 'This is line_<m>'
    NR==FNR {         # If Number of records equal to relative number of records, i.e. first file is being parsed
        a[$2];        # store $2 as a key in associative array 'a'
        next          # Don't process further. Go to next record.
    } 
    !($2 in a)        # Print a line if $2 of that line is not a key of array 'a'
' file2 file1

附加要求评论中

如果我在一行中有多个“:”:“line_1:这个:is:line0” 不起作用。怎么才能只走line_x

在这种情况下,请尝试以下操作(仅限GNU awk

awk -F'line_[0-9]+:' 'NR==FNR {a[$2]; next} !($2 in a)' file2 file1

【讨论】:

  • 如果“差异”位于文件 2 中,此命令将失败。换句话说,如果两个文件都有“差异”,则 anwer 中的 awk 方法将不起作用。
  • @Kent 同意。但是这个解决方案是基于 OP 的命令comm -23 file1 file2,我相信这意味着 file1 独有的行。如果我遗漏了什么,请纠正我。
  • 没错。实际上我需要file1和file2之间的一种差异。我正在使用 comm -23 file1 file2 和 comm -23 file2 file1
  • @georgiana_e 那么您正在寻找comm -2。在这种情况下,diff 是更好的命令。 Bdw,如果您只想遵循您的方法,那么您不能通过交换 file1 和 file2 将相同的逻辑应用于我的解决方案吗?
  • 似乎可以解决您的问题,但请您稍微解释一下。我不明白它在做什么。
【解决方案2】:

这条 awk 行更长,但是无论差异位于何处,它都可以工作:

awk 'NR==FNR{a[$NF]=$0;next}a[$NF]{a[$NF]=0;next}7;END{for(x in a)if(a[x])print a[x]}' file1 file2

测试:

kent$  head f*
==> f1 <==
line_1: This is line0
line_2: This is line1
line_3: This is line2
line_4: This is line3

==> f2 <==
line_1: This is line1
line_2: This is line2
line_3: This is line3

#test f1 f2
kent$  awk 'NR==FNR{a[$NF]=$0;next}a[$NF]{a[$NF]=0;next}7;END{for(x in a)if(a[x])print a[x]}' f1 f2
line_1: This is line0

#test f2 f1:    
kent$  awk 'NR==FNR{a[$NF]=$0;next}a[$NF]{a[$NF]=0;next}7;END{for(x in a)if(a[x])print a[x]}' f2 f1
line_1: This is line0

【讨论】:

  • 我想在没有 line_$NR 的情况下在 file1 file2 之间做差异,然后使用 awk 插入 line_$NR?
  • 我不希望测试 f2 f1 返回与测试 f1 f2 相同的输出。同样在文件 2 中,我将“This is line 2”更改为“This is line 5”,输出为:“line_2: This is line5 line_1: This is line0 line_3: This is line2”
猜你喜欢
  • 2016-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 2011-03-29
  • 2022-01-01
  • 1970-01-01
相关资源
最近更新 更多