私は多くのディレクトリとサブディレクトリを持っています。ディレクトリから特定のファイルを再帰的に削除したいと思います(そのファイルがディレクトリ内の唯一のファイルである場合)。また、このディレクトリにはサブディレクトリがないとします。したがって、要約すると、仮説は次のようになります。
- ファイル名はREADME.TXTです(大文字と小文字を区別しません)。
- ファイルが見つかったディレクトリに他のファイルやディレクトリがありません。
構造:
mkdir usecase
cd usecase
mkdir destroy_this
touch destroy_this/readme.txt
mkdir do_not_destroy_this
touch do_not_destroy_this/readme.txt
touch do_not_destroy_this/something-else.txt
mkdir do_nothing
cd do_nothing
mkdir rm_this
touch rm_this/README.TXT
cd ..
mkdir do_nothing_here
cd do_nothing_here
mkdir has_sub_dir
touch README.TXT
cd ..
上記のコードを実行すると、次のツリー構造が生成されます。
$ tree .
.
`-- usecase
|-- destroy_this
| `-- readme.txt
|-- do_not_destroy_this
| |-- readme.txt
| `-- something-else.txt
|-- do_nothing
| `-- rm_this
| `-- README.TXT
`-- do_nothing_here
|-- has_sub_dir
`-- README.TXT
これが私が今まで得たものです:
find . -type f -iname "readme.txt" -exec sh -c 'ls $(dirname "{}") | wc -l' \;
アイデアは、ファイルとディレクトリの数を数え、1つであればファイルを削除することです。
答え1
あなたが持っているのが良い出発点になります。コンテンツを変更する場合は、カウントステータスが1であるかどうかに応じて動作できる設定を-exec
導入できます。if/then
$ find . -type f -iname "readme.txt" -exec \
sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
then echo "yes"; \
else echo "no"; \
fi' \;
no
yes
yes
no
このようにecho "yes"
コマンドを拡張して物理ファイルの削除を実行できます。このようなことはrm "{}"
トリックを行う必要があります。
はい
$ find . -type f -iname "readme.txt" -exec \
sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
then echo "removing {}.."; rm "{}"; \
else echo "no"; \
fi' \;
no
removing ./usecase/destroy_this/readme.txt..
removing ./usecase/do_nothing/rm_this/README.TXT..
no
上記のコマンドを2番目に実行すると、ファイルが存在しなくなったことが確認されます。
$ find . -type f -iname "readme.txt" -exec \
sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
then echo "removing {}.."; rm "{}"; \
else echo "no"; \
fi' \;
no
no
答え2
find . -type f -iname "readme.txt" -exec sh -c '
for f do ls -1qap ${f%/*} |
grep -v "\(readme.txt\$\|/\$\|.\{1,2\}\$\)" &&
echo rm "$f" ; done' \{\} +