tree
コマンドを模倣し、ディレクトリ内のすべてのファイルとサブディレクトリを繰り返し、すべてのファイル名をエコーするにはどうすればよいですか?
私はディレクトリ内のサブディレクトリがまだディレクトリと見なされていると思い、次のようにしました。
for FILE in *; do
if [ -d $FILE ]
then echo "$FILE is a directory";
else echo "$FILE is a file"
fi
done
サブディレクトリ内で再帰とループを作成し、すべてのファイルを繰り返し、ファイル名+パスを印刷するにはどうすればよいですか?
bash を使用するシェルスクリプトです。ありがとうございます!
ベストアンサー1
以下は、コマンドで実装されたterdonシェル関数と同じですfind
。
find . -exec sh -c 'for f; do
[ -d "$f" ] && is_dir="" || is_dir="not "
printf "\"%s\" is %sa directory\n" "$f" "$is_dir"
done' sh {} +
またはfind&perlを使用します(各ディレクトリレベルを2つのスペースにインデントし、ファイル名区切り文字としてNULを使用します)。
find . -print0 | \
perl -0ne '$is_dir = -d $_ ? "" : "not ";
$f = $_; $indent = ($f =~ s=/==g);
printf " " x $indent . "%s is %sa directory\n", $_, $is_dir'
ほとんどのPerlの1行コードは単純で明確ですが、説明が必要な場合があります。
$f = $_; $indent = ($f =~ s=/==g);
これは$_
現在の入力レコード(つまりファイル名)を変数にコピーします$f
。次に、/
変更回数を変数に保存しながら$ fを変更してすべての文字を削除します$indent
。$f
これは廃止され、変更を防ぐための1回限りの変数です$_
。
この変数は、printf形式の文字列を構築するために$indent
反復演算子(x
乗算に似ていますが、文字列については参照)と一緒に使用されます。man perlop
ファイルとディレクトリの数を数えるには、1行に3桁の広い数字を使用します。
$ find . -print0 | perl -0ne '
if ( -d $_ ) {
$is_dir = "";
$dirs++
} else {
$is_dir = "not ";
$files++
};
$f = $_; $indent = ($f =~ s=/==g);
#printf " " x $indent . "%s is %sa directory\n", $_, $is_dir;
printf "%3i: " . " " x $indent . "%s is %sa directory\n", $., $_, $is_dir;
END {
# simple method to determine singular or plural word forms
# without using the Lingua::EN::Inflect module
# (see https://metacpan.org/release/Lingua-EN-Inflect)
my $d_word = ($dirs != 1) ? "directories" : "directory";
my $f_word = ($files != 1) ? "files" : "file";
print "\n$dirs $d_word, $files $f_word\n";
}'
この行のPerl部分は、コマンドラインで編集することがもはや合理的ではない点に達しました。とんでもない長い行を扱うのは完全なPITAだからです。テキストエディタを使用する方がはるかに簡単です。 $PATHのどこかにスクリプトファイル(つまり、~/bin/
存在しない場合はPATHに追加)に最初の行として保存する必要があります。/usr/local/bin
#!/usr/bin/perl -0ne
chmod +x