将结果作为第二个参数传递给awk

时间:2017-07-25 07:28:52

标签: linux bash awk process-substitution

我的命令:

awk 'NR==FNR{a[$0]=1;next;} substr($0,50,6) in a' file1 file2

问题是文件2包含\000个字符,awk将其视为二进制文件。

用空格字符替换\000

tr '\000' ' ' < file2 > file2_not_binary

解决二进制文件问题。

但是我的file2是一个20GB的文件。我不想单独执行tr并将结果另存为另一个文件。我想将tr的结果传递给awk

我试过了:

awk 'NR==FNR{a[$0]=1;next;} substr($0,50,6) in a' file1 < (tr '\000' ' ' < file2)

但结果是:

The system cannot find the file specified. 

另一个问题是:我的记忆或awk可以同时处理这么大的文件吗?我正在研发12GB RAM PC。

修改

其中一个答案正如我所预期的那样(归功于Ed Morton)

tr '\000' ' ' < file2 | awk 'NR==FNR{a[$0];next} substr($0,50,6) in a' file1 -

然而,它比2步更慢2倍 - 首先删除\000并保存,然后使用awk进行搜索。我怎样才能加快速度呢?

EDIT2

我的坏。 Ed Morton解决方案实际上比在两个单独的命令中做同样快一点。

分别使用两个命令:08:37:053

两个管道命令:08:07:204

3 个答案:

答案 0 :(得分:3)

由于awk不会将第二个文件存储在内存中,因此除了执行速度之外,该文件的大小无关紧要。试试这个:

tr '\000' ' ' < file2 | awk 'NR==FNR{a[$0];next} substr($0,50,6) in a' file1 -

答案 1 :(得分:2)

应该是:

awk ... <(tr -d '\0' < file2)
# -------^ no space!

查看有关Process Substitution

的手册

答案 2 :(得分:1)

您可以使用js在awk中替换它。测试,让我们制作一个测试文件:

gsub(/\000/," ")

然后:

$ awk 'BEGIN{print "a b\000c d"}' > foo
$ hexdump -C foo
00000000  61 20 62 00 63 20 64 0a                           |a b.c d.|
00000008