使用awk迭代unix命令nm并通过多个文件求和输出

Posted

技术标签:

【中文标题】使用awk迭代unix命令nm并通过多个文件求和输出【英文标题】:Using awk to iterate unix command nm and sum output through multiple files 【发布时间】:2017-01-31 19:27:39 【问题描述】:

我目前正在编写一个脚本,该脚本将查看 nm 的输出并使用以下方法对列 $1 的值求和

read $filename
nm --demangle --size-sort --radix=d ~/object/$filename | 
    awk ' sum+= $1  END  print "Total =" sum '

我想对任意数量的文件执行以下操作,循环访问一个目录,然后输出结果摘要。我想要每个文件的结果以及添加所有列的第一列的结果。

我仅限于使用 bash 和 awk。

【问题讨论】:

【参考方案1】:

你需要把读取的$filename放在一会儿;做; done 循环并将整个循环的输出提供给 awk。

例如

while  read filename ; do
       nm  ...  $filename 
done  |  awk 'print $0   sum+=$1  END  print "Total="sum'

awk print $0 将打印每个文件的行,以便您查看每个文件。

【讨论】:

我建议while IFS= read -r filename - 这样我们就不会从输入中删除反斜杠或前导/尾随空格。并在扩展名上引用"$filename",可能在前面加上--,以允许以破折号开头的文件名正常工作。 (因此:nm ... -- "$filename" ...除此之外,这是一个比让awk 运行子进程更好考虑的分工,因为它缺乏允许安全完成此类操作的设施。 【参考方案2】:

bash globstar 选项用于递归文件匹配 您可以在 awk 命令末尾使用 **/*.txt 之类的

$ shopt -s globstar
$ awk '
    BEGINFILE  
        c="nm --demangle --size-sort --radix=d \"" FILENAME "\"" 
        while ((c | getline) > 0)  fs+=$1; ts+=$1;   
        printf "%45s %10'\''d\n",FILENAME, fs
        close(c); fs=0; nextfile
     END  
        printf "%30s %s\n", " ", "-----------------------------" 
        printf "%45s %10'\''d\n", "total", ts 
    ' **/*filename* 

【讨论】:

如果我们有一个恶意文件名——比如说,一个使用touch './$(rm -rf $HOME)' 创建的文件——这将是非常非常不幸的。希望在充满二进制文件的目录中不存在类似的情况,但如果下一个人可能正在循环上传目录,最好不要教人们“这是用 awk 循环文件的好习惯”。

以上是关于使用awk迭代unix命令nm并通过多个文件求和输出的主要内容,如果未能解决你的问题,请参考以下文章

使用 awk 解析 nm 命令的输出 - Linux Bash

awk

awk命令详解

awk

awk命令详解和实例

awk工具的使用