現在のディレクトリ(サブディレクトリを除く)内のファイルをカウントするスクリプトを探しています。各ファイルを反復処理し、ディレクトリがカウントされない場合はカウントを増やします。出力はファイル数を表す整数でなければなりません。
私は思いついた
find . -type f | wc -l
しかし、私はそれがすべてのカウントビットを行うとは本当に思っていません。これは課題ですので、私を正しい方向に向けるだけでいいのであれば、それは素晴らしいことです。
通常のファイルのみが必要な場合は、
GNU find
:
find . -maxdepth 1 -type f -printf . | wc -c
その他のfind
s:
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 {} \;
を他のfind
sとともに、または.
を-.
とともにzsh
に変更するか、または-L
nameをls
に追加します。 get false negativesシンボリックリンクのターゲットのタイプを判別できない場合(たとえば、アクセスできないディレクトリにあるため)。
通常のファイルだけでなく、任意のタイプのファイル(シンボリックリンク、ディレクトリ、パイプ、デバイスなど)が必要な場合:
find . ! -name . -Prune -printf . | wc -c
(GNU以外で-print | grep -c /
に変更find
、(ND.)
をzsh
で(ND)
に、grep -c '^-'
をls
でwc -l
に変更)。
ただし、.
を..
でls
に置き換えない限り、-A
または-a
はカウントされません(通常、これらは常に存在するため、実際には考慮されません)。
ディレクトリを除くすべてのタイプのファイルが必要な場合は、-type f
を! -type d
に置き換え(または! -xtype d
を使用してディレクトリへのシンボリックリンクも除外します)、zsh
に置き換え、.
を^/
に置き換え、ls
に置き換え、grep -c '^-'
をgrep -vc '^d'
に置き換えます。
隠しファイルを除外する場合は、! -name '.*'
を追加するか、zsh
を使用してD
を削除するか、ls
を使用してA
を削除します。
サブディレクトリを除外するには
find . -maxdepth 1 -type f | wc -l
これは、ファイル名に改行文字が含まれておらず、findの実装が-maxdepth
オプションをサポートしていることを前提としています。
現在のディレクトリのすべてに対してiterateを実行するには、次を使用します。
for f in ./*; do
次に、どちらかを使用します
[ -f "$f" ]
または
test -f "$f"
取得したものが通常のファイル(またはファイルへのシンボリックリンク)かどうかをテストします。
これは、ソケットまたは他の点で特別なファイルを除外することに注意してください。
ディレクトリを除外するだけを使用するには、
[ ! -d "$f" ]
代わりに。
変数の引用は重要です。たとえば、hello world
というディレクトリとhello
というファイルが存在する場合は、誤ってカウントされるためです。
hiddenファイル(ファイル名に.
が先行するファイル)にも一致させるには、dotglob
シェルオプションにshopt -s dotglob
(bash
)、または使用
for f in ./* ./.*; do
これらのグロブパターンが何にも一致しないときにシェルが何も返さないようにする場合は、nullglob
シェルオプション(bash
内)を設定することをお勧めします(そうしないと、リテラル文字列./*
および./.*
in f
)。
注:これは割り当てであるため、完全なスクリプトを指定することは避けます。
#!/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
埋め込まれた改行やその他の印刷できない文字を含むファイルを処理するものが必要な場合は、このソリューションが機能します。しかし、それはあなたの割り当てにとってはほぼ間違いなくやり過ぎです。
find . -maxdepth 1 -type f -print0 | tr -dc '\0' | wc -c
これにより、各ファイル名の末尾の\0
以外のすべてが破棄されます。次に、それらの文字をカウントし、ファイルの数を示します。
次に、現在のディレクトリ内の(ディレクトリ以外の)ファイルの数をカウントしてエコーする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を設定しないでください。