
ループを使ってやりたいですfor
。これは私が今まで考えたものですが、うまくいきません。
for home in /home/ {.,/}*; do echo "$home"; done
可能であれば、非再帰的にこれを行いたいと思います。
答え1
forはfind
現在のディレクトリのディレクトリタイプではないため、再帰は必要ありません。
find . ! -name . -prune ! -type d | grep -c /
...ディレクトリに対してのみ2番目の爆発を削除するか、-type
すべてのファイル形式のテストを完全に削除してください。
この場合、再帰がないと、ファイルごとに1つのパス区切り文字しか表示されないため、計算する項目と計算する場所に混乱がないため、簡単です。ファイル数を数える必要があるときに改行文字を数えると、問題が発生する可能性があります。 2つのことは互いに関連していません。では、何ができますか?
find .//. | grep -c '^\.//\.'
...子オブジェクトの正確な数と現在のディレクトリにルートを持つオブジェクトを返します。
また、動作しますが、反対のロジックを使用します。内部的に改行を引用し、stat()
各設定ファイルの代わりに各ディレクトリだけが必要なので、おそらくより速いでしょう。
\ls -1qRA . | grep -Exc \[^/]+
-R
このオプションを破棄すると、ls
再帰なしで動作します。
ただし、上記は、ファイル名のマルチバイト文字と互換性のないロケールによって誤った数を返す可能性があります。LC_ALL=C
POSIX 準拠の環境に配置すると、ls
このようなことは起こらず、かなり大きなツリーの深さの数を使用すると、最終的にはパフォーマンスにのみ役立ちます。
答え2
必要なタスクをほとんど実行できるより高いレベルのコマンドがたくさんありますが、これはシェルスクリプトで同じタスクを実行する方法を示す良い例です。これはうまくいくはずですどのシステムは/bin/sh
他のコマンドに依存しません。
このスクリプトを任意のファイル名とタイプで保存してsh ./whatever_you_named_it
実行できます。
二つの部分に分けたが、ファイルのリストとファイル数の計算。ファイルを再帰的にリストするのは最も複雑ですが、リストがあれば簡単に数えることができます。
ファイルのリスト
このスクリプトは、ホームディレクトリまたは引数として受け取るディレクトリの下のすべてのファイルとディレクトリを繰り返し一覧表示します。パラメータがない場合、デフォルトはホームディレクトリです。
#!/bin/sh
if test $# -eq 0
then
startdir="$HOME"
else
startdir="$1"
fi
for f in "$start"/* # step through all files in the starting directory
do
echo "$f" # print the file name
if test -d "$f" # is the file a directory? (-d)
then
sh "$0" "$f" # yes call this script with the dir as arg
fi
done
各段階について議論しましょう。
引数がスクリプトに渡されない場合は、「$ HOME」が開始ディレクトリとして使用され、そうでない場合は最初の引数が使用されます。 ($#にはスクリプトに渡された引数の数が含まれており、ゼロであることを
test
確認するためにシェルの組み込みコマンドを使用します):if test $# -eq 0 then startdir="$HOME" else startdir="$1" fi
ホームディレクトリのファイルを繰り返します。
"$HOME"/*
ホームディレクトリの最上位レベルで隠されていないすべてのファイルとディレクトリに展開します。for f in "$HOME"/* do
ファイル名を印刷します。私はあなたが知っていると思います
echo
:echo "$f" # print the file name
optionsを使用してシェル組み込み
test
コマンドを呼び出します-d
。test
引数がディレクトリ"$f"
の場合はtrueを返します。これは通常[ -d "$f" ]
簡潔に書かれていますが、実際にはコマンドです。 ["test expr"のマニュアルページを検索sh
]:if test -d "$f" # is the file a directory? (-d) then
次の声明は私たちが繰り返すところです。現在実行中のスクリプトの新しいコピーを開始し、ここに現在の「$ f」ディレクトリ名を渡します。
$0
現在のシェルスクリプトのファイル名に展開されます。ここにファイル名を入力するのではなく、$0
名前が変更されてもスクリプトが機能するようにする方法です。たとえば、スクリプトが呼び出されたときに作成することrlist
もできますが、sh rlist "$f"
スクリプトの名前が変更された場合は存在しないスクリプトまたは無効なスクリプトを呼び出すため、スクリプトは正しく実行されません。 [マンページの「特殊パラメータ」を参照sh
]:sh "$0" "$f" # yes call this script with the dir as arg
if
ステートメントとループを終了しますfor
。fi done
ファイル数の計算
これまで、スクリプトはファイルを一覧表示しますが、計算しません。すべてのファイルとディレクトリの数を取得するには、次のコマンドを実行します。
sh ./scriptname | wc -l
wc -l
「単語数」コマンドで、-l
このオプションがある行のみを計算します。上記のパイプは、ホームディレクトリのファイル数である数字を印刷します。
答え3
使用探す:
非再帰的であるということは、サブディレクトリではなく/homeのファイル/ディレクトリの数だけが欲しいという意味ですか?この場合、このオプションを使用して結果を最上位レベルに制限できますmaxdepth
。
find /home -maxdepth 1 | wc -l
使用:
i=0; for home in ~/*; do (( i++ )); done; echo $i
二重括弧と周囲のi++の間のスペースに注意してください。