如何使用 xargs 将 awk 或其他表达式的输出求和

如何使用 xargs 将 awk 或其他表达式的输出求和

假设我有以下 bash shell 脚本:

#!/bin/bash
export  count=0;
for i in `ls ./mydoc` ;do

     pdfinfo ./mydoc/$i | egrep Pages |awk {'print $2'} |xargs -+ $count   ;
                                                        ^^^^^^^^^^^^^^^^^
done;

echo $count;

它枚举了每个 pdf 文件的页面,但我不知道如何将它们加在一起。 !!!!!

答案1

只需在 awk 中执行即可,忘记 xargs。

awk '{total += $2} END {print total}'

但您只需要运行 awk 一次,并将循环的所有输出都通过管道传输到其中。为什么不删除单独的 grep 呢......

for i in mydoc/* ; do
    pdfinfo $i
done | awk '/^Pages/ { total += $2 } END { print total }'

答案2

尝试一下内置的计算方法:

#!/bin/bash
count=0
for i in ./mydoc/* ; do
  count=$(( $count + $(pdfinfo "$i" | grep Pages |awk {'print $2'}) ))
done
echo $count

答案3

艾伦接受的awk答案很好,但这里有一个使用xargs和 的通用解决方案bc。这个想法是以某种方式生成一个数字列表,用于xargs将它们全部连接在一行上,并用空格分隔,然后用于sed将空格更改为+字符(tr也可以)。通过管道将其输入 bc 中。

可以使用相同的方法从字符串/正则表达式列表构造正则表达式,只需将空格更改为|(扩展正则表达式) 或\|(基本正则表达式) 而不是+

for i in mydoc/* ; do pdfinfo $i ; done | \
  awk '/^Pages/ {print $2}' | xargs | sed -e 's/ /+/g' | bc

注意:如果生成了数千个数字,超出了 shell 的命令行长度限制,xargs 可能会生成多行。由于 的输出bc符合“以某种方式生成数字列表”,解决方案是再次将 的输出通过管道传输bcxargs | sed -e 's/ /+/g' | bc

for i in mydoc/* ; do pdfinfo $i ; done | \
  awk '/^Pages/ {print $2}' | xargs | sed -e 's/ /+/g' | bc | \
  xargs | sed -e 's/ /+/g' | bc

xargs | sed -e 's/ /+/g' | bc | xargs | sed -e 's/ /+/g' | bc当然,可以将其放入 shell 脚本、函数或别名中。

这是使用此方法构造正则表达式的示例。如果 search.txt 包含 foo、bar、baz、quux(每行一个单词),则:

$ cat search.txt | xargs | sed -e 's/ /|/g'
foo|bar|baz|quux

无用的 use-of-cat 是此示例的占位符 - 替换为生成单词或正则表达式模式列表的任何管道。

如果任何搜索模式包含空格字符,则必须在管道输入之前暂时将它们更改为其他内容(选择不太可能出现在输入中的内容),xargs然后在sed.例如,如果 search.txt 的“bar”行有一个尾随空格:

$ cat search.txt | sed -e 's/ /XXX_SPACE_CHARACTER_XXX/g' | xargs | sed -e 's/ /|/g' -e 's/XXX_SPACE_CHARACTER_XXX/ /g'
foo|bar |baz|quux

相关内容