指定されたディレクトリを通過し、30日以内に使用されたファイルが含まれていないファイルを自動的に圧縮するスクリプトがあります。私はexecでfindを使ってパフォーマンスを向上させることができるかどうか疑問に思います。いくつか試してみましたが、うまくいきません。おすすめメニューとは何ですか?
#!/bin/bash
# find all the directories
dirs=`find . -type d`
# iterate every file in every directory
for dir in $dirs
do
n="totar"
# search all the file in the directory
files=`find $dir -type f -atime -30`
for file in $files
do
n="keepasis"
done
if [ $n == "totar" ]; then
tar -zcvf $dir.tgz $dir
rm -r $dir
fi
done
私の考えは、2番目のforループを次に置き換えることです。
find $dir -type f -atime -30 -exec n="keepasis" {} \;
答え1
find
ジョブで変数を設定すると、その-exec
変数は表示されません。
ファイルが見つかり、その名前が印刷されるという事実だけで、そのディレクトリを保持しないとfind
判断するのに十分です。したがって、ループする必要はありませんが空ではfor file in $files
ないことを確認してください$files
。
find
コマンドがこれをサポートしている場合は、-quit
それを使用して最初の一致後に停止できます。 (望むより最初の一致後にfindコマンドをどのように停止できますか?)
最初の出力の出力を変数に入れ、トークン化でforループを使用する代わりに、Limeの出力を1行ずつ読み取ることをお勧めしfind
ます。find
#!/bin/bash
# find all the directories
# -mindepth 1 prevents "find" from printing "."
find . -mindepth 1 -type d | while read -r dir
do
# a subdirectory might no longer exist if a parent has been archived before
if [ -d "$dir" ]
then
# search any new file in the directory
newfilefound=`find $dir -type f -atime -30 -print -quit`
if [ -z "$newfilefound" ]
then
tar -zcvf $dir.tgz $dir
rm -r $dir
fi
fi
done
find
Bashを使用している場合は、特殊文字を含むより多くのディレクトリ名を正しく処理するように最初のものを改善できますfind . -type d -print0 | while IFS= read -r -d '' dir; do
。
それでもパフォーマンスの問題があります。
ディレクトリのサブディレクトリのどこかに新しいファイルが含まれている場合は、そのファイルを削除しないでください。後でこのファイルを含むすべてのサブディレクトリの名前が取得されます。この場合、find
同じ新しいファイルを見つけるために複数回使用されます。
私の心に浮かぶ唯一の解決策は、2つfind
、いくつかの後処理と1つを使用することですfgrep
。
- すべての新しいファイルの名前を印刷し
find
、ファイル名を削除して出力を処理し、すべての親ディレクトリを別々の行に印刷し、重複エントリを削除し、リストをNEWDIRSファイルに入れます。 - 2番目は、
find
すべてのディレクトリ名を2番目のファイルALLDIRSに出力します。 fgrep
NEWDIRSの行と一致しないALLDIRSのすべての行を見つけるために使用されます。
tar
ディレクトリを削除する前に、コマンドが成功したことを確認する必要があります。