我想使用 bash 脚本或命令来查找名称非常相似但仅括号内部分不同的文件。例如
Filename (year1)
Filename (year2)
应该匹配。
或者更具体地说,
Filename (2000)
Filename (2001)
应该匹配。
答案1
以下脚本的工作原理是将位置参数列表设置为与模式匹配的名称列表*' ('*')'
,即当前目录中名称中包含空格且末尾带有括号的所有文件。
该脚本使用双循环将每个名称与所有其他名称进行比较。为了避免将某个名称A
与其他名称进行比较B
,然后再B
与 进行比较A
,我们在外部迭代开始时移出列表的第一个元素。这也避免了针对名称A
本身进行测试。
在内部循环中,我们删除名称末尾的括号并比较两个结果字符串。如果字符串相同,我们就打印名称。
#!/bin/sh
set -- *' ('*')'
for name do
shift
for dup do
if [ "${name%% (*)}" = "${dup%% (*)}" ]; then
printf '"%s" <-> "%s"\n' "$name" "$dup"
fi
done
done
答案2
虽然晚了,但我想我应该贡献一个小的 Bash 脚本,用 Gawk 处理文件名。它标记任何给定目录中文件之间的各种欺骗。尽管文件对只检查一次,但处理仍然是 O(n^2)。
在感兴趣的目录中运行脚本,例如在包含以下内容的目录中:
$ \ls -A -1
2323- (1236).suffix
23232(1234).suffix
23232 (1236).hsj
23232 (1236).suffix
hello(2001.10.29)fgh.ssh
hello(2002.10.29)fgh.ssh
23232(1236).suffix
23232(12 6).suffix
23232 (1286).suffix
23232 (1446).suffix
23232(3236).suffix
dwlkl(1234).sds
现在的脚本:
$ cat near_match.sh
#!/usr/bin/env bash
gawk '
{i++; a[i] = $0; next} # put files to check in array 'a'
END {
nfiles = i; # number of files to check
for (i = 1; i <= nfiles-1; i++) {
lblkarr1 = split(a[i], blkarr1, "[()]");
lparr1 = split(blkarr1[2], parr1, "");
for (j = i+1; j <= nfiles; j++) {
lblkarr2 = split(a[j], blkarr2, "[()]");
lparr2 = split(blkarr2[2], parr2, "");
mismatch = 0;
if ("x"blkarr1[1]"x" == "x"blkarr2[1]"x" && "x"blkarr1[3]"x" == "x"blkarr2[3]"x" && lparr1 == lparr2) {
for (k=1; k<=length(blkarr1[2]); k++) { if (parr1[k] != parr2[k]) mismatch++ };
if (mismatch == 1) printf "dupes: %s <--> %s\n", a[i], a[j];
}
}
}
}' <<< $(\ls -A -1 -- *"("*")"*)
exit 0
使脚本可执行并不带参数运行。
$ near_match.sh
dupes: 23232(1234).suffix <--> 23232(1236).suffix
dupes: 23232 (1236).suffix <--> 23232 (1286).suffix
dupes: hello(2001.10.29)fgh.ssh <--> hello(2002.10.29)fgh.ssh
dupes: 23232(1236).suffix <--> 23232(12 6).suffix
dupes: 23232(1236).suffix <--> 23232(3236).suffix
- 正如 OP 所指定的,“dupe”专门定义为括号内的 1 个字符不匹配。调整解决方案以扩展它,以便可以在文件名中的任何位置检测到字符不匹配是微不足道的。
- 括号可以位于文件名中的任何位置,并且文件名可以有任何后缀或没有后缀。
- 所提出的解决方案似乎对文件名中的特殊字符(附加括号除外)具有鲁棒性。
- 只需进行最少的更改即可将 1 字符不匹配更改为多字符不匹配。通过输入脚本的参数来改变这个数字是微不足道的。询问是否必须。
华泰