質問
- 私はディレクトリを再帰的に検索し、一意の隠しファイルおよび/または隠されたディレクトリのすべてのサブディレクトリ(最大深度まで)を含むパスを返すことができるBashコマンドを作成しようとしました。
視覚的な説明
- 次のファイルシステムの抜粋を検討してください。
+--- Root_Dir
| +--- Dir_A
| | +--- abc.txt
| | +--- 123.txt
| | +--- .hiddenfile
| | +--- .hidden_dir
| | | +--- normal_sub_file_1.txt
| | | +--- .hidden_sub_file_1.txt
| |
| +--- Dir_B
| | +--- abc.txt
| | +--- .hidden_dir
| | | +--- normal_sub_file_2.txt
| | | +--- .hidden_sub_file_2.txt
| |
| +--- Dir_C
| | +--- 123.txt
| | +--- program.c
| | +--- a.out
| | +--- .hiddenfile
| |
| +--- Dir_D
| | +--- .hiddenfile
| | +--- .another_hiddenfile
| |
| +--- Dir_E
| | +--- .hiddenfile
| | +--- .hidden_dir
| | | +--- normal_sub_file_3.txt # This is OK because its within a hidden directory, aka won't be checked
| | | +--- .hidden_sub_file_3.txt
| |
| +--- Dir_F
| | +--- .hidden_dir
| | | +--- normal_sub_file_4.txt
| | | +--- .hidden_sub_file_4.txt
希望の出力
- 私が探しているコマンドが出力されます。
./Root_Dir/Dir_D ./Root_Dir/Dir_E ./Root_Dir/Dir_F
Dir_D
隠しファイルだけが含まれているからです。Dir_E
私が探しているレベルの隠しファイルと隠されたディレクトリだけが含まれているからです。Dir_F
私が探しているレベルの隠しディレクトリだけが含まれているからです。
努力する
- そのコマンドを使用して
find
目的の結果を取得しようとしていますが、出力をパイプするために必要な他のコマンドが何であるか、使用する必要がある他のオプションが何であるかがわかりません。 - 有効なコマンドは次のとおりです。
bob@linux:/$ find ./Root_Dir -mindepth 2 -maxdepth 2 -type d -name "*." -type -f -name "*." | command to see if these are the only files in that directory
ベストアンサー1
私はこれに対してあまり良くない解決策を持っています。
スクリプト形式:
#!/bin/bash
# Echo whatever is passed to fail, and then exit with a status of 1
fail() {
echo >&2 "$@"
exit 1
}
# If the number of arguments are less or more than what
# we expect, throw help syntax and exit.
if [ $# -gt 2 ] || [ $# -lt 2 ]
then
fail "
$0 check for directories that only contain hidden listings
Usage: $0 <Directory to search from> <Depth to check>
"
fi
# Assign parameters
root_dir=$1
depth=$2
# Find a list of directories that contain files OR subdirectories
# that are hidden
readarray -t dirs < <(export LC_ALL=C
find "$root_dir" -mindepth "$depth" -maxdepth "$depth" \
-name ".*" \( -type d -o -type f \) -execdir pwd \; | sort -u
)
# Of the dirs we found, do any of them return any listings with a
# default ls execution? If so, that directory cannot only contain
# hidden listings.
final=()
for dir in "${dirs[@]}"
do
notExclusive="$(ls -- "$dir")"
if [ "$notExclusive" = "" ]
then
final+=("$dir")
fi
done
# The array final contains the directories who only contain hidden
# files/subdirectories.
printf '%s\n' "${final[@]}"
デフォルトでは、隠しリスト(質問で指定された深さ2)を含むディレクトリを見つけて配列にロードし、ls
フラグが何も返さない場合は、ディレクトリに隠されたリストのみが含まれており、標準を満たすと結論付けることができます。
find
OPの説明に基づいて一度だけ呼び出す理由を説明してください。コマンドfind
には基本ロジックの演算子があります。 -aは、論理ANDで2つの式を結合するときのデフォルトの動作です。論理NOTでは、-oは論理ORと同じです。
この方法は、ディレクトリパスに改行文字が含まれていないと仮定し、含まれている場合はreadarray
各ディレクトリパスを誤って区別します。
醜い「一行」:
readarray -t dirs < <(export LC_ALL=C; find ./Root_Dir -mindepth 2 -maxdepth 2 -name '.*' \( -type d -o -type f \) -execdir pwd \; | sort -u); final=(); for dir in "${dirs[@]}"; do notExclusive="$(ls -- "$dir")"; if [ "$notExclusive" = "" ]; then final+=("$dir"); fi; done; printf '%s\n' "${final[@]}"