列出名称bash中编号最大的文件名

时间:2014-08-12 14:43:03

标签: bash

想象一下,我有一个名称如下的文件目录列表:

  • 0006_0001.txt
  • 0006_0002.txt
  • 0006_0003.txt
  • 0006_0004.txt
  • 0007_0001.txt
  • 0008_0001.txt
  • 0008_0002.txt
  • 0009_0004.txt
  • 0010_0002.txt

...

  • 0808_0001.txt
  • 0808_0005.txt

模式总是一样的,我想选择名称中最后一个数字最大的文件。所以在上面这种情况下,例如结果应该是:

  • 0006_0004.txt
  • 0007_0001.txt
  • 0008_0002.txt
  • 0009_0004.txt
  • 0010_0002.txt
  • 0808_0005.txt

我正在尝试类似的事情:

find . -name '*_000[1-9].AHF' | sed 's/\([0-9]_[0-9].AHF\+\).*/\1/g' | sort -n

但它不对,我猜原则上应该可以用一些sed吗?

由于

4 个答案:

答案 0 :(得分:1)

假设您在文件中有文件名,这将使它成为:

awk 'BEGIN{FS=OFS="_"} {a[$1]=(a[$1]<$2?$2:a[$1])} END {for (i in a) print i,a[i]}' file

否则,只需管道列表:

your_find_command | awk 'BEGIN{FS=OFS="_"} {a[$1]=(a[$1]<$2?$2:a[$1])} END {for (i in a) print i,a[i]}' 

解释

  • BEGIN{FS=OFS="_"}将输入和输出字段分隔符设置为_
  • {a[$1]=(a[$1]<$2?$2:a[$1])}存储第二个块的最大值,第一个块阻止数组的索引。
  • END {for (i in a) print i,a[i]}打印[希望]所需的输出。

测试

$ cat a
0006_0001.txt
0006_0002.txt
0006_0003.txt
0006_0004.txt
0007_0001.txt
0008_0001.txt
0008_0002.txt
0009_0004.txt
0010_0002.txt
0808_0001.txt
0808_0005.txt

$ awk 'BEGIN{FS=OFS="_"} {a[$1]=(a[$1]<$2?$2:a[$1])} END {for (i in a) print i,a[i]}' a
0808_0005.txt
0006_0004.txt
0007_0001.txt
0008_0002.txt
0009_0004.txt
0010_0002.txt

答案 1 :(得分:1)

你可以:

  • 按相反顺序排序,以便在顶部(sort -r
  • 上放置更大的数字
  • 删除重复项,仅检查前4个字符(uniq -w4
  • 如果您需要按照确切的顺序(tac
  • 反转行的顺序

所以命令将是:

your command | sort -r | uniq -w4 | tac

一个更有说服力的版本(使用它的好处是你可以阅读他们做的事情):

your command | sort --reverse | uniq --check-chars=4 | tac

实施例

$ cat FILE
0006_0001.txt
0006_0002.txt
0006_0003.txt
0006_0004.txt
0007_0001.txt
0008_0001.txt
0008_0002.txt
0009_0004.txt
0010_0002.txt
0808_0001.txt
0808_0005.txt

$ cat FILE | sort -r | uniq -w4
0808_0005.txt
0010_0002.txt
0009_0004.txt
0008_0002.txt
0007_0001.txt
0006_0004.txt

$ cat FILE | sort -r | uniq -w4 | tac
0006_0004.txt
0007_0001.txt
0008_0002.txt
0009_0004.txt
0010_0002.txt
0808_0005.txt

答案 2 :(得分:0)

这对您有用(假设文件以.txt结尾 - 您的名字可以,但您的代码假设结尾为.AHF):

find . -name '*_000[1-9].txt' | grep -oE '[0-9]+_[0-9]+' | sort -t _ -k 2nr

您的sed命令不正确,因为您在_的任意一侧没有匹配多个数字。但是,grep稍微清晰一点 - -o表示只输出匹配,而不是整行。

上面的命令将首先打印出第二个最高编号的行;然后按第一个数字排序增加。如果您希望两者都减少,请使用sort -t _ -k 2,1n -r

当然,这不会让你获得实际的文件名;只是数字部分。

答案 3 :(得分:0)

#!/usr/bin/awk -f
BEGIN {
    FS = "[_.]"
}
{
    t = $0
    sub(/.*\//, "")
    sub(/^0+/, "", $1)
    sub(/^0+/, "", $2)
    if ($1 in a) {
        if ($2 > b[$1]) {
            a[$1] = t
            b[$1] = $2
        }
    } else {
        keys[++k] = $1
        a[$1] = t
        b[$1] = $2
    }
}
END {
    for (i = 1; i <= k; ++i)
        print a[keys[i]]
}

用法:

find . -name '*_000[1-9].AHF' | awk -f script.awk

测试输入:

./0006_0001.txt
./0006_0002.txt
./0006_0003.txt
./0006_0004.txt
./0007_0001.txt
./0008_0001.txt
./0008_0002.txt
./0009_0004.txt
./0010_0002.txt
./0808_0001.txt
./0808_0005.txt

输出:

$ awk -f script.awk < input
./0006_0004.txt
./0007_0001.txt
./0008_0002.txt
./0009_0004.txt
./0010_0002.txt
./0808_0005.txt

该脚本也递归应用。