web-dev-qa-db-ja.com

ディレクトリ内の特定の名前のファイルの数を数える

私はこのコードをここに見つけました https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html これにより、ディレクトリ内のファイル数がわかります。

ls -1 | wc -l

しかし、これらのファイルの名前のうち2009年で始まる名前の数だけを知りたい(たとえば、20091210_005037.nc)。

私は試した ls -1 | wc -l 2009*しかし、それはゆっくりとすべてのファイルをリストし、私に番号を与えていないようです。

4
Jellyse
_set -- 2009*
echo "$#"
_

これにより、位置パラメータ(_$1_、_$2_、...など)のリストが_2009*_に一致する名前に設定されます。このリストの長さは_$#_です。


_ls -1 | wc -l 2009*_の問題は、_wc -l_に一致するファイルに対して_2009*_を直接実行し、それぞれの行数を数えることです。その間、_ls -1_はwcの標準入力に書き込もうとしています。wcは、作業対象のファイルの明示的なリストが与えられたため、そこから読み取っていません。

_ls -d 2009* | wc -l_を使用したいと思うかもしれません。これは、_2009*_に一致するすべての名前をリストし(lsを_-d_と一緒に使用して、ディレクトリの内容をリストしない)、出力の行数をカウントします。 lsの結果をどこかにパイプする場合、_-1_は必要ありません(lsが列出力を強制するエイリアスまたはシェル関数でない限り)。

また、ファイル名に改行が含まれている場合はwrongカウントが表示されることにも注意してください。

_$ touch '2009
> was
> a
> good
> year'
$ ls
2009?was?a?good?year
$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 May 28 11:09 2009?was?a?good?year
$ ls -1
2009?was?a?good?year
$ ls | wc -l
       5
$ ls -1 | wc -l
       5
_

しかしながら:

_$ set -- 2009*
$ echo "$#"
1
_

setを使用して_$#_を出力すると、ほとんどのシェルで外部コマンドは使用されません)


findを使用して再帰的にカウントする:

_find . -type f -name '2009*' -exec echo . \; | wc -l
_

ここでは、現在のディレクトリ内またはその下で見つかったパス名ごとにドットを出力し、これが生成する行数をカウントします。ファイル名の文字列自体はカウントせず、ファイル名に改行が含まれている場合に行数が多くなりすぎないように、この方法でカウントします。

findを使用すると、カウントするファイルのtypeをより厳密に制御できます。上記では、_-type f_を使用して通常のファイルを明示的にテストします(つまり、ディレクトリや他のタイプのファイルではありません)。シェルの_*_パターンはディレクトリとファイルを区別しませんが、zshシェルは*(.)を使用してパターンの動作を変更し、通常のファイル( zshユーザーは、上と下のfind以外のバリエーションで_2009*_の代わりに2009*(.)を使用する可能性があります)。

_**_ in(_shopt -s globstar_ in bash、または_set -o extended-glob_ in yash、またはそれをサポートする他のシェル)を使用して再帰的にカウントする:

_set -- **/2009*
echo "$#"
_

パターン_**_は_*_とほとんど同じように一致しますが、パス名の_/_全体にも一致します。

10
Kusalananda

以下のコマンドで試してみましたが、うまくいき、結果が出ました

   find . -maxdepth 1 -type f -iname "2009*" | awk '{print NR}'| sed -n '$p'

注:サブディレクトリの下にもしたい場合は、親切にmaxdepthオプションを削除してください

2

コメントの人々のおかげで、これは私の質問への答えです:

ls 2009* | wc -l

または検索を使用して

find 2009* | wc -l
1
Jellyse

Awkを使用して、特定のファイル名で始まるファイルの数をカウントします。

root@ubuntu$ find . -name "2009*" | awk 'BEGIN{total=0}; {total=total+1} END {print "total files starting with 2009 is " ,total}'
total files starting with 2009 is  4
0
Goron