在bash中删除多个目录中同名的文件

在bash中删除多个目录中同名的文件

使用具有以下架构的 bash 语言

 - directory1
        - entries
 - directory2
        - entries

我想删除重复的条目,只保留其中一个。我使用以下脚本:

for dir in *
do 
    [ -d "$dir" ] && for file in "$dir"/*
    do 
        filename=$(basename "$file")
        find . -name "$filename" -not -path "*$dir*" -exec rm "{}" \;
    done
done

我一直面临的问题是,当目录被清空时,filename="*"。因此 find 将返回所有条目并删除所有内容。

由于我使用的机器无法访问互联网,因此我无法使用任何工具。

答案1

添加以下测试即可达到目的:

for dir in *
do 
    [ -d "$dir" ] && [ "$(ls -A $dir)" ] && for file in "$dir"/*
    do 
        filename=$(basename "$file")
        find . -name "$filename" -not -path "*$dir*" -exec rm "{}" \;
    done
done

答案2

有了你的解决方案,我不明白你如何保留一个. 如果文件 'f' 位于目录 'A' 和 'B' 中:

  • 当外部 for 循环位于“A”上时,find 将打印 B/f。
  • -------------------------------------------'B',------------------ A/f。

但是,您什么也不要做,只是打印。

我建议这样做,不要在 for 中嵌套 find :

只有一个.sh:

#!/bin/sh
tmp=$(mktemp -d)
dir=$1

for d in "$dir"/*; do
  if [ -d "$d" ]; then
    for f in "$d"/*; do
      bf=$(basename "$f")
      if [ -a "${tmp}/$bf" ]; then
        rm "$f"
      else
        touch "${tmp}/$bf"
      fi
    done
  fi
done

rm -rf "$tmp"

基本上,会创建一个(空的)新临时目录 $tmp。然后,对于每个文件 $f,如果 $tmp 包含一个具有相同文件名的文件,则删除该文件 $f,否则在 $tmp 中创建一个具有该文件名的文件。

yarl@badaboum:~/work$ ls
foo  there_can_be_only_one.sh
yarl@badaboum:~/work$ ls -R foo/
foo/:
dir0  dir1  dir2

foo/dir0:
de  hello  mammouth

foo/dir1:
arg  de  heart  hello

foo/dir2:
arg  blarg  de

yarl@badaboum:~/work$ ./there_can_be_only_one.sh foo/
yarl@badaboum:~/work$ ls -R foo/
foo/:
dir0  dir1  dir2

foo/dir0:
de  hello  mammouth

foo/dir1:
arg  heart

foo/dir2:
blarg

相关内容