繁体   English   中英

cat管awk操作与awk命令在文件上的比较

[英]Comparison of cat pipe awk operation to awk command on a file

在尝试优化我的服务器相关数据时,我和我的团队讨论了linux命令的用法。 请求会员请帮助我们更准确地理解这个概念。

在服务器上,我们有每分钟创建的日志文件,我们需要搜索具有特定标签的日志,例如:错误日志,超时日志,请求失败日志。 在许多中,一个要求是提供有关这些标签计数的信息

简单的逻辑是将特定字段(带分隔符)awk到sort和uniq -c命令来计算此类实例的数量。

我可以看到两种方法来执行它:

cat fname | awk -F":" {'print $1'} | sort | uniq -c

awk -F":" {'print $1'} fname | sort | uniq -c

文件大小可以以GB为单位,因此命令可能更有效。

有3种方法可以打开文件并让awk对其内容进行操作:

  1. cat打开文件:

     cat file | awk '...' 
  2. shell重定向打开文件:

     awk '...' < file 
  3. awk打开文件

     awk '...' file 

其中的选择:

  1. 总是要避免,因为cat和管道正在使用资源并且没有提供任何价值,谷歌UUOC(无用的猫)的细节。

使用其他2个中的哪个是值得商榷的:

  1. shell的优点是打开文件而不是工具,因此如果对所有工具执行此操作,则可以依赖一致的错误处理
  2. 具有以下优点:该工具知道它正在操作的文件的名称(例如,awk中的FILENAME),因此您可以在内部使用它。

要查看差异,请考虑以下两个文件:

$ ls -l file1 file2
-rw-r--r-- 1 Ed None 4 Mar 30 09:55 file1
--w------- 1 Ed None 0 Mar 30 09:55 file2
$ cat file1
a
b
$ cat file2
cat: file2: Permission denied

看看当你尝试使用两种打开它们的方法对两者的内容运行awk时会发生什么:

$ awk '{print FILENAME, $0}' < file1
- a
- b

$ awk '{print FILENAME, $0}' file1
file1 a
file1 b

$ awk '{print FILENAME, $0}' < file2
-bash: file2: Permission denied

$ awk '{print FILENAME, $0}' file2
awk: fatal: cannot open file `file2' for reading (Permission denied)

请注意,当您使用重定向时打开不可读文件file2的错误消息来自shell,所以看起来就像我第一次尝试cat时的错误消息,而当awk打开它时出现错误信息来自awk并且是与shell消息不同,并且在各种awk中会有所不同。

请注意,当使用awk打开文件时,FILENAME会填充正在操作的文件的名称,但是当使用重定向打开文件时,它被设置为-

我个人认为“3”(填充的FILENAME)的好处远大于“2”(文件打开错误的一致错误处理)的好处,因此我总是使用:

awk '...' file

并针对您使用的特定问题:

awk -F':' '{cnt[$1]++} END{for (i in cnt) print cnt[i], i}' fname

使用以下方法应该避免绝对无用的cat

awk -F":" '{print $1}' fname | sort | uniq -c

但我的建议是通过使用以下方法在awk找到唯一的项目来避免昂贵的sortuniq命令:

awk -F":" '!seen[$1]++' fname

这将打印出独特的线条。

获得独特的数量:

awk -F":" '!count[$1]++{c++} END{print c}' fname

cat fname | 因为它必须将文件从磁盘复制到内核然后再转移到cat的缓冲区,然后再转移到管道,然后再转到内核,再转到另一个进程,因此减慢了一点。 它不是很多,因为它应该只是一个线性减速和内存中复制非常快,但你总是可以(=不依赖some_command接受文件参数)通过替换加快速度

cat one_file_name | some_command 

<one_file_name some_command

这将是更快,因为它会直接设置one_file_name作为stdinsome_command

<one_file_name可以并且经常放在some_command 之后和下一个管道符号之前。 我个人经常喜欢从它开始,因为它反映了cat( cat one_file_name )的无用但有些常见用法的从左到右的流程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM