web-dev-qa-db-ja.com

ディレクトリ内のファイルをカウントするスクリプト

現在のディレクトリ(サブディレクトリを除く)内のファイルをカウントするスクリプトを探しています。各ファイルを反復処理し、ディレクトリがカウントされない場合はカウントを増やします。出力はファイル数を表す整数でなければなりません。

私は思いついた

find . -type f | wc -l

しかし、私はそれがすべてのカウントビットを行うとは本当に思っていません。これは課題ですので、私を正しい方向に向けるだけでいいのであれば、それは素晴らしいことです。

6
user182477

通常のファイルのみが必要な場合は、

GNU find

find . -maxdepth 1 -type f -printf . | wc -c

その他のfinds:

find . ! -name . -Prune -type f -print | grep -c /

(改行文字を含むファイル名がある場合は機能しないため、-print | wc -lは必要ありません)。

zshの場合:

files=(*(ND.)); echo $#files

lsの場合:

ls -Anq | grep -c '^-'

通常のファイルへのシンボリックリンクを含めるには、-type f-xtype fにGNU find、または-exec test -f {} \;を他のfindsとともに、または.-.とともにzshに変更するか、または-Lnameをlsに追加します。 get false negativesシンボリックリンクのターゲットのタイプを判別できない場合(たとえば、アクセスできないディレクトリにあるため)。

通常のファイルだけでなく、任意のタイプのファイル(シンボリックリンク、ディレクトリ、パイプ、デバイスなど)が必要な場合:

find . ! -name . -Prune -printf . | wc -c

(GNU以外で-print | grep -c /に変更find(ND.)zsh(ND)に、grep -c '^-'lswc -lに変更)。

ただし、...lsに置き換えない限り、-Aまたは-aはカウントされません(通常、これらは常に存在するため、実際には考慮されません)。

ディレクトリを除くすべてのタイプのファイルが必要な場合は、-type f! -type dに置き換え(または! -xtype dを使用してディレクトリへのシンボリックリンクも除外します)、zshに置き換え、.^/に置き換え、lsに置き換え、grep -c '^-'grep -vc '^d'に置き換えます。

隠しファイルを除外する場合は、! -name '.*'を追加するか、zshを使用してDを削除するか、lsを使用してAを削除します。

10

サブディレクトリを除外するには

find . -maxdepth 1 -type f | wc -l

これは、ファイル名に改行文字が含まれておらず、findの実装が-maxdepthオプションをサポートしていることを前提としています。

3
user4556274

現在のディレクトリのすべてに対してiterateを実行するには、次を使用します。

for f in ./*; do

次に、どちらかを使用します

[ -f "$f" ]

または

test -f "$f"

取得したものが通常のファイル(またはファイルへのシンボリックリンク)かどうかをテストします。

これは、ソケットまたは他の点で特別なファイルを除外することに注意してください。

ディレクトリを除外するだけを使用するには、

[ ! -d "$f" ]

代わりに。

変数の引用は重要です。たとえば、hello worldというディレクトリとhelloというファイルが存在する場合は、誤ってカウントされるためです。

hiddenファイル(ファイル名に.が先行するファイル)にも一致させるには、dotglobシェルオプションにshopt -s dotglobbash)、または使用

for f in ./* ./.*; do

これらのグロブパターンが何にも一致しないときにシェルが何も返さないようにする場合は、nullglobシェルオプション(bash内)を設定することをお勧めします(そうしないと、リテラル文字列./*および./.* in f)。

注:これは割り当てであるため、完全なスクリプトを指定することは避けます。

3
Kusalananda
#!/bin/bash

# initialize counter
count=0;

# go through the whole directory listing, including hidden files
for name in * .*
do
    if [[ ! -d $name ]]
    then
        # not a directory so count it
        count=$(($count+1))
    fi
done

echo $count
2
Julie Pelletier

埋め込まれた改行やその他の印刷できない文字を含むファイルを処理するものが必要な場合は、このソリューションが機能します。しかし、それはあなたの割り当てにとってはほぼ間違いなくやり過ぎです。

find . -maxdepth 1 -type f -print0 | tr -dc '\0' | wc -c

これにより、各ファイル名の末尾の\0以外のすべてが破棄されます。次に、それらの文字をカウントし、ファイルの数を示します。

1
roaima

次に、現在のディレクトリ内の(ディレクトリ以外の)ファイルの数をカウントしてエコーするbashスクリプトを示します。

#!/usr/bin/env bash
i=0
shopt -s nullglob dotglob
for file in *
do
  [[ ! -d "$file" ]] && i=$((i+1))
done
echo "$i"

"nullglob"を設定すると、現在のディレクトリにファイル(非表示またはそれ以外)がない場合に正しくカウントされます。 nullglobを未設定のままにすると、forループが*という1つの項目を(誤って)参照することになります。

"dotglob"を設定すると、.でグロブするときに、隠しファイル(*で始まるファイル)も含めるようにbashに指示します。デフォルトでは、隠しファイルのリストを生成するときに、bashは.または..[〜#〜] globignore [〜#〜] を参照)を含めません。割り当てで隠しファイルをカウントしたくない場合は、dotglobを設定しないでください。

1
Jeff Schaller