删除所有不重复名称的文件?

删除所有不重复名称的文件?

给定一个很大的文件列表,包含以下内容:

FILE1.doc
FILE1.pdf
FILE2.doc
FILE3.doc
FILE3.pdf
FILE4.doc

是否有终端命令允许我删除列表中没有重复名称的所有文件?在这种情况下...FILE2.doc 和 FILE4.doc?

答案1

使用 bash,这将删除所有没有同名但扩展名不同的文件的文件:

for f in *; do same=("${f%.*}".*); [ "${#same[@]}" -eq 1 ] && rm "$f"; done

这种方法对于所有文件名都是安全的,即使是那些名称中含有空格的文件名。

怎么运行的

  • for f in *; do

    这将启动当前目录中所有文件的循环。

  • same=("${f%.*}".*)

    这将创建一个 bash 数组,其中包含具有相同基本名称的所有文件的名称。

    $f是我们文件的名称。 ${f%.*}是不带扩展名的文件名。例如,如果文件是FILE1.doc,则文件${f%.*}FILE1"${f%.*}".*是具有相同基本名称但具有任意扩展名的所有文件。 ("${f%.*}".*)是这些名称的 bash 数组。 same=("${f%.*}".*)将数组分配给变量same

  • [ "${#same[@]}" -eq 1 ] && rm "$f"

    如果只有一个具有该基本名称的文件,我们将其删除。

    "${#same[@]}" 是数组中的文件数same[ "${#same[@]}" -eq 1 ]如果只有一个这样的文件,则为 true。

    &&是逻辑与。rm "$f"仅当其前面的语句返回逻辑 true 时,它​​才会执行后面的语句。

  • done

    这标志着循环的结束for

答案2

假设您的文件列表位于某个文件中/tmp/files.list,例如之后ls * > /tmp/files.list

然后sort -u /tmp/files.list为您提供一个没有重复的排序文件列表(如果您执行了上述操作,则不需要 ls * > /tmp/files.list)。你可以用一些处理它awk剧本灵感来自,例如

sort -u /tmp/files.list | awk '{
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
curfil=$0;
if (basename(curfil)==basename(prevfil)) system("rm " + curfil);
prevfil=curfil;
}'

请注意,我还没有测试过这个。

答案3

另一种看似简单但复杂的方法可以是:

for x in `for i in *; do echo $i ; done | cut -d'.' -f1 | uniq -u `; do rm $x.*; done

相关内容