我有大量文件,如下所示:
Some Name da-1234567-1.py
Some Name da-1234567-2.py
Some Name da-1234567-4.py
Other Name di-5678912-3.py
Other Name di-5678912-4.py
Other Name di-5678912-5.py
我想删除所有版本并只保留:
Some Name da-1234567-4.py
Other Name di-5678912-5.py
我意识到我的问题类似于查找最新的文件夹/文件版本并删除 - 无时间戳数据。然而,它的答案对我不起作用,我对 bash 和/或正则表达式的了解不足以改变解决方案来满足我的需求。不幸的是,我没有声誉评分来发表评论,因此除了发布新问题之外,我没有其他选择。
我从上面的问题中尝试了以下操作:
for file in *.*
do
[[ -d "$file" || $file =~ _[[:digit:]]{3}\. ]] && continue
echo -n "Considering $file: " >&2
extn="${file/*.}"
versions=("$file")
keep="$file"
# Look at matching files
for version in "${file%.$extn}"_???."$extn"
do
[[ -f "$version" ]] || continue
# Save every one. Identify the current last
versions+=("$version")
keep="$version"
echo -n "$version " >&2
done
echo "==> keep $keep" >&2
# Delete them all except the last
for version in "${versions[@]}"
do
[[ "$version" != "$keep" ]] && echo rm -f -- "$version"
done
[[ "$keep" != "$file" ]] && echo mv -f -- "$keep" "$file"
done
我意识到这部分可能会出错:
$file =~ _[[:digit:]]{3}\.
,因为与上述问题相反,我的文件结尾是 -n 而不是 _nnn,但我不知道如何修复它。
答案1
软件工具一行,使用ls -v
并按sort -V
版本号排序:
{ ls -Qrv *.py |rev | uniq -f 1 | rev; ls -Q *.py; } | sort -V | uniq -u | xargs rm
使用uniq -f 1
取决于文件命名格式是否一致——rev
需要周围的 s,因为-f
没有其他方法可以忽略最后一个字段。
答案2
和zsh
:
# all *.<number>.py files in "n"umerical order
files=(*-<->.py(n))
# associative array whose key is the part before the last "-"
typeset -A latest
for f ($files) latest[${f%-*}]=$f
# plain array with the values of the associative array
keep=($latest)
# array subtraction:
echo rm -- ${files:|keep}
(如果高兴就删除echo
)。
这没有假设其余文件名可能包含哪些字符。使用bash
(或zsh
或ksh
) 和 GNU 工具:
xargs -r0a <(printf '%s\0' *-*.py |
grep -zEe '-[[:digit:]]+\.py$' |
sort -zrV |
awk -vRS='\0' -vORS='\0' '
{key = $0; sub(/-[^-]*$/, "", key)}
seen[key]++') echo rm --