删除除最新版本之外的所有版本 - 没有时间戳

删除除最新版本之外的所有版本 - 没有时间戳

我有大量文件,如下所示:

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(或zshksh) 和 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 --

相关内容