xargsを使用してawkまたは他の式の出力を合計する方法

xargsを使用してawkまたは他の式の出力を合計する方法

次のようなbashシェルスクリプトがあるとしましょう。

#!/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

Alanのawk答えは素晴らしいですが、次のようなxargs一般的な解決策がありますbc。アイデアは、xargs空白で区切られた1行にすべての数字を連結するために使用できる数値のリストを生成し、空白をsed文字+に変更するために使用できることです(trこれも機能します)。 BCにパイプします。

同じ方法を使用して、文字列/正規表現のリストで正規表現を構成できます。代わりに、スペースを|(拡張正規表現)または\|(デフォルト正規表現)に変更するだけです+

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

注: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もちろん、これをシェルスクリプト、関数、またはエイリアスに入れることもできます。

以下は、この方法を使用して正規表現を構成する例です。 search.txtにfoo、bar、baz、quaux(1行に1語)が含まれている場合:

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

役に立たないuse-of-catはこの例のプレースホルダーです。単語リストまたは正規表現パターンを生成するパイプに置き換えられます。

検索パターンに空白文字が含まれている場合は、入力をパイプする前に(入力に表示される可能性が低い項目を選択する)、一時的に別のものに変更する必要があります。たとえば、search.txtの「bar」行にあるとしますxargssed末尾のスペースがあります。

$ 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

関連情報