如何用 Find 进行列表比较?

如何用 Find 进行列表比较?

我这样做并获得了一个文件列表,我想在其中删除许多重复的备份文件

find . -type f -name '._*' 

我想找到那些具有相应文件名的文件

  • /home/masi/._test.tex火柴/home/masi/test.tex
  • /home/masi/math/lorem.png火柴/home/masi/math/._lorem.png

关于要保存的文件的伪代码filename,其中有对应._filename但也保存filename没有._filename

find . -type f -name '._*' -exec \ 
   find filenameWithoutDotUnderscore, if yes, print the filename

伪代码 2 关于要删除的文件的说明 =._filename是否有相应的filename

  • 如果在同一目录中存在filename和,请打印以便我可以删除重复的 = 。._filename._filename._filename
  • 排除filenamePart1_.filenamePart2, bok_3A.pdf, ... 中的._filename
  • 如果同一目录下 ._filename没有对应的,请勿删除。filename

检查通配符的命令

我这样做了find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +,但它返回了太多文件。我认为&&除了存在性检查之外我还需要更多条件([ -e "$f" ])。如果怀疑有很大差异,最好能在这里进行一些内容比较,最后进行比较。

系统:Ubuntu 16.04 和 Debian 8.25
Bash:4.3.42
查找:4.7.0

答案1

您可以使用 来做到这一点find,但为了稳健地做到这一点,您还需要嵌入一个 shell 单行代码。执行此操作的正确方法是以下之一:

将循环填充到生成的 shell 中:

find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} +

或者,为每个要测试的文件生成一个单独的 shell(效率较低,但可能更具可读性):

find . -type f -name '._*' -exec sh -c 'f="${1%/*}/${1##*/._}"; [ -e "$f" ] && printf %s\\n "$f"' find-sh {} \;

要直接删除备份文件,请将其更改为以下内容试运行:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf "rm -- %s\n" "$a"; done' find-sh {} +

然后一旦你满意了对于打印的命令列表,请使用:

find . -type f -name '._*' -exec sh -c 'for a; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && rm -- "$a"; done' find-sh {} +

笔记:

在所有这些中,find-sh参数是任意字符串;你可以把任何东西放在那里。它被设置为$0在生成的 shell 中,并用于错误报告。

for a in "$@"; do完全等同于for a; do.

printfecho

引用很重要

相关内容