ディレクトリ内のすべてのファイルの行数を人間が読める形式でどのようにリストしますか。


40

大きなcsvファイルを含むディレクトリとサブディレクトリのリストがあります。これらのファイルには約5億行あり、それぞれがレコードです。私が知りたいのですが

  1. 各ファイルの行数。
  2. ディレクトリ内の行数。
  3. 合計何行

最も重要なことは、「人間が読める形式」でこれが必要なことです。12345678ではなく12,345,678

3つの方法でこれを行う方法を学ぶといいでしょう。プレーンバニラバッシュツール、awkなど、およびperl(またはpython)。

回答:


56

各ファイルの行数。

を使用してwc、元は単語数をカウントしますが、行、単語、文字、バイト、および最長行長を実行できます。この-lオプションは、行をカウントするように指示します。

wc -l <filename>

これにより、次の行数が出力されます。

$ wc -l /dir/file.txt
32724 /dir/file.txt

データをパイプすることもできwcます:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

ディレクトリ内の行数。

試してください:

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

別のワンライナー:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

ところで、wcコマンドは行ではなく、改行コードをカウントします。ファイルの最後の行が改行コードで終了していない場合、これはカウントされません。

grep -c ^を使用できます。完全な例:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

合計何行

リクエストを正しく理解したかどうかわかりません。たとえば、これは次の形式で結果を出力し、各ファイルの行数を示します。

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

または、次のコマンドにファイル数ごとのファイルなしで改行文字の総数だけを出力するには、次のコマンドが役立ちます。

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

最も重要なことは、「人間が読める形式」でこれが必要なことです。12345678ではなく12,345,678

Bashにはprintf関数が組み込まれています:

printf "%0.2f\n" $T

いつものように、ここで述べた同じ結果を達成するために使用できる多くの異なる方法があります。


ところで、例でprintfを使用するにはどうすればよいですか?wc -lからパイプしようとしましたが、うまくいきませんでした。
ヘキサトニック

try> find -name '* .pl' | xargs wc -l | awk '{printf( "%0.2f"、$ 1)} {print $ 2}'は、ニーズに合わせて 'printf'の出力を変更します
malyy

ただし、人間が読みやすいように番号にコンマを追加しません。最後にゼロを追加するだけです。
ヘキサトニック

エコー1000000000000 | xargs printf "% 'd \ n" 1,000,000,000,000
16進

1
@Hexatonicはprintfからその引数を読んでいないstdinのではなく、コマンドラインから(への配管比較echoへの配管対cat; catから読み込みstdinechoしません)。代わりに、を使用printf "$(find ... | xargs ...)"してを引数として出力を提供しますprintf
BallpointBen

13

多くの場合、wcコマンドとワイルドカードを組み合わせる*だけで十分です。
すべてのファイルが単一のディレクトリにある場合は、次を呼び出すことができます。

wc -l src/*

複数のファイルとディレクトリをリストすることもできます。

wc -l file.txt readme src/* include/*

このコマンドは、ファイルとその行数のリストを表示します。
最後の行は、すべてのファイルの行の合計になります。


ディレクトリ内のすべてのファイルを再帰的にカウントするには:

まず、shopt -s globstar.bash_profileに追加してglobstarを有効にします。globstarのサポートにはbrew install bash、必要に応じてインストールできるBash≥4.xが必要です。でバージョンを確認できますbash --version

次に実行します:

wc -l **/*

globstarが有効になっていない場合、この出力は正しくないことに注意してください。


現在のディレクトリ内のファイルを再帰的にカウントする場合:wc -l **/*
テイラーエドミストン

@TaylorEdmiston私(Macの場合)は、1つ下のディレクトリだけをファイルとしてカウントします。それは、現在のディレクトリ内のファイルをスキップして、複数のディレクトリになります任意のインスタンスに対して深いそれがディレクトリだと警告している:「wc: parent_dir/child_dir: read: Is a directory
M.ジャスティン

@Thomio globstarを有効にする必要があります。macOSでは、デフォルトで無効になっていると思います。コマンドとglobstarを有効にする方法を追加する回答を編集しました。
テイラーエドミストン

2

このコマンドは、各ディレクトリの行コードのリストを提供します。

find . -name '*.*' -type f | xargs wc -l

2

ゲームに少し遅れましたが、dirのサイズが原因で、上記の引数エラーが大量に発生しました。これは私のために働いた:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt


0

catファイルを1つにまとめてすべてをstdoutに出力します。wc -lディレクトリ内のファイルの合計行数に対してそれを行うことができます:

cat /path/to/directory/* | wc -l

0

私は次の@malyyの答えを増やすだけです(コメントのために大きくなります):

合計何行

多くの答えは、wcコマンドラインファイルオプションを使用していxargsます。これに関する問題は、xargsがプラットフォームに依存するかなり小さなサイズに制限されていることです。

さらに、BSD(macOS)とGNU(linux / homebrew)には違いがありますwc

GNUのものは、引数(--files0)の代わりにファイルからファイルリストを読み取ることができるため、理想的です。

Macを使用していて自家製の場合は、次のことを行う必要があります。

find . -name "*.pl" -print0 | gwc -l --files0=-

wcの代わりにgwcに注意してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.