如果特定文件是唯一的,则从目录中删除该文件

如果特定文件是唯一的,则从目录中删除该文件

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

  • 文件名为 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

您所拥有的一切是一个良好的起点。如果您修改了您的内容,-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

这样我们就可以扩展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

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

$ 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' \{\} +

相关内容