删除行的语法

删除行的语法

我使用此语法删除2.txtto中的行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

你需要:

  1. 告诉 awk 您正在使用:字段分隔符,并且
  2. 使用字段作为数组索引而不是整行,并且
  3. 测试是否存在索引而不是值

即这样做:

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 填充内存12.txta[]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

相关内容