Awk 非grep方法从另一个文件中出现字符串的文件中删除行

Awk 非grep方法从另一个文件中出现字符串的文件中删除行,awk,sed,grep,Awk,Sed,Grep,我知道之前已经回答了一些类似的问题,但我还没有找到我想要的(并且尝试了各种各样的解决方案)。希望这是一个简单的问题 我有一个标签分隔的文件(file.txt),有10列,大约50万行,简化后的格式如下: ID Col1 Col2 Col3 a 4 2 8 b 5 6 1 c 8 4 1 d 3 5 9 e

我知道之前已经回答了一些类似的问题,但我还没有找到我想要的(并且尝试了各种各样的解决方案)。希望这是一个简单的问题

我有一个标签分隔的文件(file.txt),有10列,大约50万行,简化后的格式如下:

ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
c        8        4        1
d        3        5        9
e        8        5        2
我想删除第一列(ID)中出现的所有行,比如“b”和“d”。我想要的输出是:

ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2
在我的输出文件中维护ID的顺序是很重要的

实际上,我想删除大约100000行。因此,我有一个参考文件(referencefile.txt),其中列出了我希望从file.txt中删除的所有ID。在本例中,引用文件仅在连续行中包含“b”和“d”

目前我正在使用grep,虽然它可以工作,但速度却慢得令人痛苦

grep -v -f referencefile.txt file.txt
有没有一种方法可以使用awk或sed(或者其他任何方法)来加速这个过程

非常感谢


AB

使用
awk

awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile

# OR

awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile

# To exclude line from infile, where list of ids from id_lists 
# exists in first field of infile
awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile

# To include line from infile, where list of ids from id_lists 
# exists in first field of infile
awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
测试结果:

输入

$ cat infile 
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2

$ awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2
输出

$ cat infile 
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2

$ awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2
但是“b”和“d”是为了说明,我实际上已经说过了 我需要删除大约100000个ID。所以我要所有的证件 在单独的文件(referencefile.txt)中列出

如果您有一个包含如下ID列表的文件

排除ID列表

$ cat id_lists
a
b

$ awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile
ID     Col1      Col2     Col3
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
包括ID列表

$ cat id_lists
a
b

$ awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile
ID     Col1      Col2     Col3
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1

使用
awk

awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile

# OR

awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile

# To exclude line from infile, where list of ids from id_lists 
# exists in first field of infile
awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile

# To include line from infile, where list of ids from id_lists 
# exists in first field of infile
awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
测试结果:

输入

$ cat infile 
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2

$ awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2
输出

$ cat infile 
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR>1 && $1 ~ /^([bd])$/{ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2

$ awk 'FNR>1 && ($1 == "b" || $1 == "d"){ next } 1' infile
ID     Col1      Col2     Col3
a        4        2        8
c        8        4        1
e        8        5        2
但是“b”和“d”是为了说明,我实际上已经说过了 我需要删除大约100000个ID。所以我要所有的证件 在单独的文件(referencefile.txt)中列出

如果您有一个包含如下ID列表的文件

排除ID列表

$ cat id_lists
a
b

$ awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile
ID     Col1      Col2     Col3
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1
包括ID列表

$ cat id_lists
a
b

$ awk 'FNR==NR{ids[$1];next}FNR>1 && ($1 in ids){next}1' id_lists infile
ID     Col1      Col2     Col3
c        8        4        1
d        3        5        9
e        8        5        2
$ awk 'FNR==NR{ids[$1];next}FNR==1 || ($1 in ids)' id_lists infile
ID     Col1      Col2     Col3
a        4        2        8
b        5        6        1

有很多方法可以加快grep本身的速度

我建议:

  • -F
    -F referencefile.txt
    中的输入视为固定字符串,而不是正则表达式

  • -w
    匹配单词

  • 可能
    LC_ALL=C
    -使用
    LC_ALL
    环境变量指示grep使用ascii而不是UTF-8


    • 有一些方法可以加快grep本身的速度

      我建议:

      • -F
        -F referencefile.txt
        中的输入视为固定字符串,而不是正则表达式

      • -w
        匹配单词

      • 可能
        LC_ALL=C
        -使用
        LC_ALL
        环境变量指示grep使用ascii而不是UTF-8


      谢谢Akshay,但“b”和“d”只是为了说明,我实际上有大约100000个ID需要删除。因此,我希望所有这些ID都列在一个单独的文件(referencefile.txt)中。@GB44444:我添加了两个解决方案,一个用于include,另一个用于excludingPerfect。非常感谢你!谢谢Akshay,但是“b”和“d”只是为了说明,我实际上有大约100000个ID需要删除。因此,我希望所有这些ID都列在一个单独的文件(referencefile.txt)中。@GB44444:我添加了两个解决方案,一个用于include,另一个用于excludingPerfect。非常感谢你!