使用具有以下架构的 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