假设我有以下 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
符合“以某种方式生成数字列表”,解决方案是再次将 的输出通过管道传输bc
到xargs | 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