给定一个变量值的输入文件(示例):
A
B
D
什么是从另一个文件中删除以上述值之一开头的所有行的脚本?例如文件内容:
A
B
C
D
最终会是:
C
输入文件大约有 100,000 个变量值。要修改的文件大约有几百万行。
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
...
但我不确定这会比循环快,然后你就不得不担心 RE 元字符出现在 file1 中。
但是,如果您在 file1 中的所有值都是真正的单个字符,那么这种创建用于 RE 比较的字符列表的方法可能对您很有效:
awk 'NR==FNR{list = list $0; next} $0 !~ "^[" list "]"' file1 file2
您可以使用comm
显示两个文件不共有的行,如下所示:
comm -3 file1 file2
将打印:
C
请注意,为此,必须对两个文件进行排序,如果它们没有排序,您可以使用绕过它
comm -3 <(sort file1) <(sort file2)
您还可以使用以下方法实现此目的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 中的值之一开头的行。