【问题标题】:BASH - remove line if first column content appears in another fileBASH - 如果第一列内容出现在另一个文件中,则删除行
【发布时间】:2016-09-03 00:16:52
【问题描述】:

如果我有两个文件。文件 A 看起来像:

a 1
a 2
a 3
b 4
c 5

我有文件 B,其中有内容:

a
b

对于出现在文件 B 和文件 A 的第 1 列中的所有内容,我想删除这些行。所以文件 A 的预期输出应该是:

c 5

非常感谢任何帮助!

【问题讨论】:

  • 编写一个 awk 脚本,创建一个数组,其键是文件 B 中的所有行。然后当它处理文件 A 时,如果 $0 not in array 打印该行。
  • 其他列是否可以包含文件 B 中的字符串?如果没有,你可以使用grep -v -f fileB -w fileA

标签: bash shell command-line file-processing


【解决方案1】:

GNU awk:

awk 'ARGIND == 1 { del[$0]++ } ARGIND == 2 && !del[$1]' B A

在处理第一个文件时(ARGIND 为 1),通过递增其条目将 $0(每一整行)输入到关联数组 del

在处理第二个文件时,如果第一个字段$1 没有与del 中的非零计数相关联,则打印。

当然,我们将B 设为第一个文件,将A 设为第二个。

(当ARGIND == 2 && !del[$1] 模式表达式产生一个布尔真值时,打印动作是隐式的。没有动作的模式具有等效于{ print } 的隐式动作)。

ARGIND 不在 POSIX 中。在可移植的 Awk 代码中,可以使用丑陋的 hack 来区分第一个文件和第二个文件:

awk 'FNR == NR { del[$0]++ } FNR < NR && !del[$1]' B A

处理第一个文件时,“文件记录数”(当前文件中的记录数)等于“总记录数”(所有文件处理的绝对记录数)。当然,如果第一个文件根本不包含任何记录,这就会中断。见What is "NR==FNR" in awk?

【讨论】:

    【解决方案2】:

    以下将完成工作,

    awk 'FNR==NR{map[$1]=1;next;}map[$1]==""{print;}' <fileB> <fileA>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2021-04-21
      • 2022-01-24
      • 2012-06-28
      • 2013-01-12
      • 2015-01-01
      • 1970-01-01
      相关资源
      最近更新 更多