从文件中删除所有行的可扩展方式,其中行以多个值之一开始

时间:2013-07-11 14:05:35

标签: linux bash sed awk

给定变量值的输入文件(示例):

A
B
D

另一个文件中删除所有以上述值之一开头的行的脚本是什么?例如,文件内容:

A
B
C
D

最终会成为:

C

输入文件的大小为100,000个变量值。要修复的文件大约有数百万行。

3 个答案:

答案 0 :(得分:3)

awk '

    NR==FNR {     # IF this is the first file in the arg list THEN
        list[$0]  #     store the contents of the current record as an index or array "list"
        next      #     skip the rest of the script and so move on to the next input record
    }             # ENDIF

    {                                # This MUST be the second file in the arg list
        for (i in list)              # FOR each index "i" in array "list" DO
            if (index($0,i) == 1)    #     IF "i" starts at the 1st char on the current record THEN
                next                 #         move on to the next input record
     }

     1  # Specify a true condition and so invoke the default action of printing the current record.

' file1 file2

构建数组然后对每个元素进行字符串比较的另一种方法是构建一个正则表达式,例如:

...
list = list "|" $0
...

然后进行RE比较:

...
if ($0 ~ list)
    next
...

但是我不确定它是否比循环更快,你必须担心在file1中出现RE元字符。

如果file1中的所有值都是真正的单个字符,那么创建用于RE比较的字符列表的方法可能适合您:

awk 'NR==FNR{list = list $0; next} $0 !~ "^[" list "]"' file1 file2

答案 1 :(得分:1)

您可以使用comm来显示两个文件不常用的行,如下所示:

comm -3 file1 file2

将打印:

      C

请注意,要实现此目的,必须对这两个文件进行排序,如果它们未排序,则可以使用

绕过它们
comm -3 <(sort file1) <(sort file2)

答案 2 :(得分:1)

您也可以使用egrep

来实现此目的
egrep -vf <(sed 's/^/^/' file1) file2

让我们看看它的实际效果:

$ cat file1
A
B
$ cat file2
Asomething
B1324
C23sd
D2356A
Atext
CtestA
EtestB
Bsomething
$ egrep -vf <(sed 's/^/^/' file1) file2
C23sd
D2356A
CtestA
EtestB

这将删除以file1中的一个值开头的行。