web-dev-qa-db-ja.com

awkまたは他の式の出力をxargsで合計する方法

次の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ファイルのページを列挙しますが、それらを合計する方法がわかりません。 !!!!!

3
PersianGulf

Awkでそれを行うだけで、xargsを忘れてください。

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

ただし、ループのすべての出力をパイプで接続して、awkを1回だけ実行する必要があります。そして、別のgrepも削除してみませんか...

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

アランによって受け入れられたawkの答えは良いですが、これはxargsbcを使用した一般的な解決策です。アイデアは、何らかの方法で数値のリストを生成し、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、quux(1行に1ワード)が含まれている場合:

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

useless-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
2
cas