我使用此语法删除2.txt
to中的行1.txt
:
awk 'NR==FNR{a[$0]=1;next}!a[$0]' 2.txt 1.txt > lines.txt
我的行采用以下格式:
[email protected]:something
如果这行在两个文件中是相同的,我就lines.txt
没有这个,所以很好,但是如果[email protected]
相同的话我想删除行并忽略后面的单词:
。
答案1
用这个:
awk -F: 'NR==FNR{a[$1]=1;next}!a[$1]' 2.txt 1.txt > lines.txt
-F:
- 将分隔符设置为:
(冒号),然后仅使用第一个字段 ( $1
) 进行比较。
答案2
你需要:
- 告诉 awk 您正在使用
:
字段分隔符,并且 - 使用字段作为数组索引而不是整行,并且
- 测试是否存在索引而不是值
即这样做:
awk -F':' 'NR==FNR{a[$1]; next} !($1 in a)' 2.txt 1.txt > lines.txt
当你这样做时,当你先读取 populate ,然后再读取时,NR==FNR{a[$1]=1; next} !a[$1]
你会不必要地用 s 填充内存1
2.txt
a[]
1.txt
您将该$1
文件中的所有内容添加到a[]
因为这样做会在索引a["foo"]
中创建一个条目,从而不必要地消耗[通常很多]更多内存,从而减慢脚本速度,如果第二个文件足够大,则可能导致脚本失败。a[]
"foo"
通常,对于这些类型的问题,第一个文件的值比第二个文件少得多,因此只是为了让您了解两种方法之间的时间差,假设您要打印 file2 中属于或不属于其中之一的行假设 file1 有 1000 行,file2 有 1000 万行,则 file1 中的行数。我们可以使用以下命令创建输入:
$ awk 'BEGIN{for (i=1; i<=1000; i++) print "foo"i}' > file1
$ awk 'BEGIN{for (i=1; i<=10000000; i++) print "foo"i}' > file2
然后测试打印 file2 中 file1 中的行:
$ time awk 'NR==FNR{a[$0]=1;next}a[$0]' file1 file2 >/dev/null
real 0m4.279s
user 0m3.375s
sys 0m0.796s
$ time awk 'NR==FNR{a[$0];next}$0 in a' file1 file2 >/dev/null
real 0m1.453s
user 0m1.343s
sys 0m0.046s
并测试打印 file2 中不在 file1 中的行:
$ time awk 'NR==FNR{a[$0]=1;next}!a[$0]' file1 file2 >/dev/null
real 0m5.549s
user 0m4.828s
sys 0m0.656s
$ time awk 'NR==FNR{a[$0];next}!($0 in a)' file1 file2 >/dev/null
real 0m2.701s
user 0m2.640s
sys 0m0.000s