行を読むときの外部bashの合計

行を読むときの外部bashの合計

.jsフォルダ内のファイルの行数の合計を計算しようとしています。私はこれをbashで使います:

sum=0 && find . | grep ".js" | while read -r f; do wc -l $f | awk '{print $1;}'; done;

$sum += $1内容物を入れてもawk無駄です。どうすればいいですか?

PS:これを使用すると、達成するのがより簡単であることがわかります。

find . -name '*.js' | xargs wc -l

私はまだ上記の解決策が欲しい。

答え1

次のシンプルで超高速のソリューションをお試しください。

find . -type f -name "*.js" -exec cat {} + | wc -l

以前はいくつかの回避策を試しましたが、wcファイル名に改行などの問題が発生したか、遅くなりました。

答え2

lastpipebashは、シェルオプションが有効になっていない限り、別々のサブシェルでパイプラインの各コマンドを実行します。

# bash requires job control to be disabled for lastpipe setting
set +m
shopt -s lastpipe

declare -i sum=0
find . -name '*.js' -print0 | while IFS= read -d '' -r name; do
    (( sum += $(wc -l < "$name") ))   # redirect the file into wc for easier output
done
echo $sum

プロセスの交換このサブシェルの問題は非常に便利に対処できます。

declare -i sum=0
while IFS= read -d '' -r name; do
    (( sum += $(wc -l < "$name") ))   # redirect the file into wc for easier output
done < <(
    find . -name '*.js' -print0
)
echo $sum

しかし、これはプログラムの流れを読みにくくする。

答え3

awk追加して結果を表示しますか?

awk '{sum +=$1} END {print sum}'これで問題が解決します。

私のBashスクリプトライブラリでは、次のことを行います。

$ find . -type f -name '*.bash' \
| while read -r f ; do wc -l "$f" ; done \
| awk '{sum +=$1} END {print sum}'

そして結果を得る522

答え4

別のbashアプローチは次のとおりです。

sum=0 && while IFS= read -r -d '' f; do let sum+=$(sed -n "\$=" "${f}"); done < <(find . -name '*.js' -print0 2>/dev/random) && echo "$sum"

find ... -print0 -- prints with null terminated 
            IFS= -- deset IFS 
   read -r -d '' -- -r do not allow backslash escapes, -d '' set delimiter to NULL
   let sum+=(..) -- add up sum of sed $= "$f", $: last line, =: line #

関連情報