从目录中删除特定文件(如果它是唯一的)

ras*_*spi 5 shell-script

我有很多目录和子目录。我想从目录中递归删除一个特定文件,如果它是唯一的一个。还假设该目录中没有子目录。因此,总而言之,假设是:

  • 文件名是 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 ..
Run Code Online (Sandbox Code Playgroud)

运行上面的将导致这个树结构:

$ 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
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所得到的:

find . -type f -iname "readme.txt" -exec sh -c 'ls $(dirname "{}") | wc -l' \;
Run Code Online (Sandbox Code Playgroud)

这个想法是我计算文件和目录的数量,如果是一个,则删除该文件。

slm*_*slm 3

您所拥有的一切是一个良好的起点。如果您修改了您的内容,-exec您可以引入一个if/then构造,该构造允许您根据计数的状态是否为 1 进行操作。

$ 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
Run Code Online (Sandbox Code Playgroud)

这样我们就可以扩展命令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
Run Code Online (Sandbox Code Playgroud)

第二次运行上述命令确认文件不再存在:

$ 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
Run Code Online (Sandbox Code Playgroud)