如何删除包含来自其他文件的字符串的行?

时间:2016-03-29 00:29:29

标签: bash awk

假设我有一个名为data的文件:

ID_11 0.3 0.5
ID_13 0.5 0.5
ID_14 0.6 0.3
ID_15 0.7 0.8
ID_16 0.9 1.0

我还有另一个文件ID

ID_11
ID_16

我想删除data中第一列与ID匹配的行。所需的输出如下:

ID_13 0.5 0.5
ID_14 0.6 0.3
ID_15 0.7 0.8

怎么做?

我在网上找到了一个命令。但我不知道是否正确。有人可以提供解释吗?

awk 'FNR==NR{a[$1];next} !($1 in a)' ID file 

5 个答案:

答案 0 :(得分:1)

你的命令对我来说很好,它也适用于我,让我解释一下命令:

<!DOCTYPE html>
<html>
<head>
<script>
  function onSuccess(isOk)
  {
  }

  google.script.run.withSuccessHandler(onSuccess)
      .doEval();
</script>
</head>
<body>
</body>
</html>
  1. $cat file1 ID_11 0.3 0.5 ID_13 0.5 0.5 ID_14 0.6 0.3 ID_15 0.7 0.8 ID_16 0.9 1.0 $cat file2 ID_11 ID_16 $awk 'NR==FNR{a[$1]++;next} !($1 in a)' file2 file1 ID_13 0.5 0.5 ID_14 0.6 0.3 ID_15 0.7 0.8 NR是您在读取一个或多个文件时保持增加的记录数,它是总文件记录数; FNR是读取文件时增加的记录文件号,读取另一个文件时重置为0,是当前文件记录号。

  2. NR==FNR如果没有提供a[$1]++;next(字段分隔符),则默认分隔符为空格,在您的情况下,FS为空格,因此没有需要提供它。将字段1(ID_XX)放入数组FS作为索引号,跳过剩余使用a

  3. next在读取第二个文件时执行,如果字段1不在数组!($1 in a)中,则将其打印出来。

答案 1 :(得分:1)

脚本的这一部分:

NR==FNR{a[$1]++;next}

将ID文件中的值保存到数组a

FNR是当前文件中的行号,NR是所有输入文件中的行号。当它们相等时,表示您正在处理第一个文件。这是您在许多脚本中看到的常见习语,其中第一个文件具有特殊角色。

a[$1]++使用第一个字段作为数组的键,并递增该数组元素。如有必要,这将创建数组元素。

next转到输入的下一行,因此它跳过任何其他代码块。

!($1 in a)
处理第二个输入文件时将执行

。它测试第一个字段是否不是处理第一个文件时创建的数组中的键。由于之后没有代码块,测试为真时的默认操作是打印输入行。

答案 2 :(得分:1)

你可以用grep:

来做到这一点
$ grep -vFwf ID data
ID_13 0.5 0.5
ID_14 0.6 0.3
ID_15 0.7 0.8

选项执行以下操作:

  • -v:反转匹配 - 打印匹配的行
  • -F:固定字符串 - 不要将模式解释为正则表达式(这里不会改变结果,可能会加速一些事情)
  • -w:单词匹配 - 仅匹配匹配为整个单词的行(避免子字符串匹配)
  • -f:从文件读取模式 - 将参数解释为文件名而不是模式

答案 3 :(得分:1)

您可以使用join

执行此操作
join -v 1 data ID

默认情况下,join使用两个文件的第一个字段。 -v 1参数仅显示第一个文件中的未配对行。

答案 4 :(得分:-1)

for line in $(cat ID); do sed '/$line/d' data; done

我不确定你的特定shell上是如何进行迭代的,但是上面的内容就是这样。