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

Passing result of tr as second parameter in awk

我的命令:

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

问题是文件 2 包含 [=15=]0 个字符,awk 将其视为二进制文件。

用space字符替换[=15=]0

tr '[=11=]0' ' ' < file2 > file2_not_binary

解决二进制文件问题。

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

我试过:

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

但结果是:

The system cannot find the file specified. 

另一个问题是:我的内存或 awk 可以一次处理这么大的文件吗?我正在使用 12GB RAM PC。

编辑

其中一个答案符合我的预期(感谢 Ed Morton)

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

然而,它比分两步执行相同操作要慢 2 倍 - 首先删除 [=15=]0 并保存,然后使用 awk 进行搜索。我怎样才能加快速度?

EDIT2

我的错。 Ed Morton 解决方案实际上比在两个单独的命令中执行相同的操作要快一点。

两个命令分开:08:37:053

通过管道传输了两个命令:08:07:204

应该是:

awk ... <(tr -d '[=10=]' < file2)
# -------^ no space!

查看有关 Process Substitution 的手册。

您可以使用 gsub(/[=12=]0/," ") 在 awk 中替换它。测试,让我们制作一个测试文件:

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

然后:

$ awk '{print; gsub(/[=11=]0/," "); print}' foo
a bc d
a b c d

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

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