ディレクトリにn行のファイル数の要約を作成しようとしています。wc -l * | sort
各ファイル名の行数を印刷するために使用しています。私が達成したいのは、以下を生成するディレクトリの要約です。
56 5
60 6
3 7
最初の列はファイル数を表し、2番目の列は行数を表します。
awk 'END{print NR}' directory/*
ディレクトリ全体の行数を返すawkコマンドを見ました。出力printf
フォーマットを指定wc -l
するソリューションを検討しました。どんな助けでも大変感謝します!ありがとう
答え1
GNUを使用すると、awk
次のことができます。
find . -type f -print0 | gawk '
BEGIN {
RS = "\0"
while ((getline < "-") > 0) ARGV[ARGC++] = $0
if (ARGC == 1) exit
RS = "\n"
}
ENDFILE {count[FNR]++}
END {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (i in count) print count[i], i
}'
find -print0
の出力からNULで区切られたファイルを読み取り、BEGINステートメントで処理するファイルのリストを設定します。
または次のようになりますperl
(空のファイルは無視されます)。
find . -type f -print0 | perl -0 -ne '
BEGIN{@ARGV = <STDIN>; $/ = "\n"}
if (eof) {$count{$.}++; close ARGV}
END {print "$count{$_} $_\n" for sort {$a <=> $b} keys %count}'
行数(区切りの有無にかかわらず)を計算し、wc -l
改行も計算します。たとえば、whereを使用してprintf foo > file
生成されたファイルはwc -l
0を報告しますが、perl
/ gawk
1を報告するため、違いがあります。
POSIXlyを使用すると、wc
次のことができます。
find .//. -type f -exec wc -l {} + | LC_ALL=C awk '
/\/\// {count[$1]++}
END {for (i in count) print count[i], i}' | sort -k2n
を使用すると、ファイルパスが.//.
出力から始まる行を知ることができwc
(//
他の場所には表示されないため)、行数が行の最初のフィールドになるため、改行を含むファイルパスを確実に処理できます。また、total
複数の引数を渡す呼び出しの終わりに印刷される行もスキップします。wc
//
GNUgrep
または互換バージョンを使用すると、次のこともできます。
LC_ALL=C grep -rch '^' . | sort -n | uniq -c
c
一致する行数を計算します^
。つまり、開始があるため、ファイル名の印刷をスキップするために、すべてのファイルのすべての行がr
繰り返さ.
れます。コンテンツをテキストにデコードすることに気を付けないでください(正規表現を考慮すると、GNUは少なくともそのデコードを最適化します)。-h
LC_ALL=C
grep
これらはすべて隠しファイルにも含まれます。
これをスキップするには、コマンドをfind
次のように変更できます。
LC_ALL=C find . -name '.?*' -prune -o -type f -print0
grep -r
-r
ファイルリストを削除して次に渡すことはできますが、find
GNUに対応するものはありませんgrep
。
LC_ALL=C find . -name '.?*' -prune -o -type f -exec grep -ch {} +
答え2
"wc -l *"が必要な方法で行を計算すると(たとえば、興味深いファイル名がない場合はuniq -cを使用して計算できます)、head -n -1は最後の "total"行を削除します。
wc -l *|head -n -1|sort|awk '{print $1}'|uniq -c