我这样做并获得了一个文件列表,我想在其中删除许多重复的备份文件
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
.