aha*_*123 1 bash ksh filenames rm
我在一个目录中有一个文件列表(比如下面的 xsl 格式)。我想保留所有文件的最后两个版本。(我可以删除剩余的文件)
{A}_1.0.xsl
{A}_2.0.xsl
{A}_3.0.xsl
{A}_4.1.xsl
{A}_5.0.xsl
{A}_6.0.xsl
{B}_1.0.xsl
{B}_2.0.xsl
{B}_3.0.xsl
{B}_4.0.xsl
{C}_1.0.xsl
{C}_2.0.xsl
{C}_3.0.xsl
Run Code Online (Sandbox Code Playgroud)
目录中存在的剩余文件应该是
{A}_5.0.xsl
{A}_6.0.xsl
{B}_3.0.xsl
{B}_4.0.xsl
{C}_2.0.xsl
{C}_3.0.xsl
Run Code Online (Sandbox Code Playgroud)
如何实现?
假设当前目录中的所有文件名都遵循该模式,使用GNUls:
ls -rv | awk -F_ '++n[$1]>2' | xargs rm
Run Code Online (Sandbox Code Playgroud)
| xargs rm如果您想检查它将首先删除的内容,您可以省略。
假设 in 部分{...}不包含空格、换行符、单引号、双引号、反斜杠、制表符或下划线字符。
关键是-vGNU 实现的ls按版本号排序的选项。如果您没有 GNU ls,但有zsh,zsh您可以使用:
print -rl -- *(nOn)
Run Code Online (Sandbox Code Playgroud)
达到同样的效果。
现在,如果当前目录可以包含任何内容,并且您只想处理形式为{x}_y.z.xslwherex可以是任何内容y并且z是正十进制整数的文件,则必须编写它(zsh语法):
printf '%s\0' \{*\}_<->.<->.xsl(.nOn) | perl -0 -lne '
unlink if /\{.*\}/s && ++$n{$&} > 2'
Run Code Online (Sandbox Code Playgroud)
或者使用GNUls 而GNU bash不是zsh:
eval "files=($(ls -rv --quoting-style=shell-always))"
printf '%s\0' "${files[@]}" | perl -0 -lne '
unlink if /^\{(.*)\}_\d+\.\d+\.xsl\z/s && ++$n{$1} > 2'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1511 次 |
| 最近记录: |