对find命令进行排序以遵守Unix中的自定义顺序

时间:2017-01-24 17:57:40

标签: linux shell sorting

我有一个脚本输出文件路径(通过find),我希望基于非常具体的自定义逻辑进行排序

  • 第一排序键: 我希望第二个和(如果存在的话)第三个- - 分隔字段使用自定义排序基于我提供的列表进行排序 - 但是< em>不包括数字后缀 通过下面的示例输入,键列表为:
    rp,alpha,beta-ri,beta-rs,RC

  • 第二个排序键:数字按每行上的尾随数字排序。

给出以下示例输入(请注意每行的/foo/bar/test/example/8.2.4.0前缀是偶然的):

/foo/bar/test/example/8.2.4.0-RC10
/foo/bar/test/example/8.2.4.0-RC2
/foo/bar/test/example/8.2.4.0-RC1
/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-beta-ri10
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-rs10
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-alpha2
/foo/bar/test/example/8.2.4.0-rp10
/foo/bar/test/example/8.2.4.0-rp2

我期待:

/foo/bar/test/example/8.2.4.0-rp2
/foo/bar/test/example/8.2.4.0-rp10
/foo/bar/test/example/8.2.4.0-alpha2
/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-ri10
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-beta-rs10
/foo/bar/test/example/8.2.4.0-RC1
/foo/bar/test/example/8.2.4.0-RC2
/foo/bar/test/example/8.2.4.0-RC10

3 个答案:

答案 0 :(得分:0)

使用my answer to your original question的变体:

./your-script | awk -v keysInOrder='rp,alpha,beta-ri,beta-rs,RC' '
    BEGIN {
      FS=OFS="-"
      keyCount = split(keysInOrder, a, ",")
      for (i = 1; i <= keyCount; ++i) keysToOrdinal[a[i]] = i
    }
    { 
      sortKey = $2
      if (NF == 3) sortKey = sortKey FS $3
      sub(/[0-9]+$/, "", sortKey)
      auxFieldPrefix = "|" FS
      if (NF == 2) auxFieldPrefix = auxFieldPrefix FS
      sub(/[0-9]/, auxFieldPrefix "&", $NF)
      sortOrdinal = sortKey in keysToOrdinal ? keysToOrdinal[sortKey] : keyCount + 1
      print sortOrdinal, $0
    }
'  | sort -t- -k1,1n -k3,3 -k5,5n | sed 's/^[^-]*-//; s/|-\{1,2\}//'

./your-script表示产生要排序的输出的任何命令。

注意一个辅助。字符|,用于促进排序,并假设此字符不会出现在输入中 - 这应该是合理安全的,因为文件系统路径通常不包含管道字符。

排序键列表中不是的任何字段2值(无数字后缀),字段2/3值后使用字母排序在他们之间进行分类。

答案 1 :(得分:0)

虽然这与OP正在寻找的不匹配,但指出sort命令有一个选项-V用于版本排序会很有用。它通过遵循ASCII表中正确的字符顺序(即首先是大写字母,然后是小写字母)来完成工作

例如:

cat test.sort.txt 
/foo/bar/test/example/8.2.4.0-RC10
/foo/bar/test/example/8.2.4.0-RC2
/foo/bar/test/example/8.2.4.0-RC1
/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-beta-ri10
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-rs10
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-alpha2
/foo/bar/test/example/8.2.4.0-rp10
/foo/bar/test/example/8.2.4.0-rp2

排序:

 % sort -V test.sort.txt              
/foo/bar/test/example/8.2.4.0-RC1
/foo/bar/test/example/8.2.4.0-RC2
/foo/bar/test/example/8.2.4.0-RC10
/foo/bar/test/example/8.2.4.0-alpha2
/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-ri10
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-beta-rs10
/foo/bar/test/example/8.2.4.0-rp2
/foo/bar/test/example/8.2.4.0-rp10

因此,在给出版本名称时要注意这一点很有用。

话虽如此,如果你坚持,这是一个使用sed强制排序的班轮:

cat test.sort.txt|sed -e 's/-rp/-x1xrp/;s/-alpha/-x2xalpha/;s/-beta-ri/-x3xbeta-ri/;s/-beta-rs/-x4xbeta-rs/;s/-RC/-x5xRC/'|sort -V|sed -e 's/x.x//'
/foo/bar/test/example/8.2.4.0-rp2
/foo/bar/test/example/8.2.4.0-rp10
/foo/bar/test/example/8.2.4.0-alpha2
/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-ri10
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-beta-rs10
/foo/bar/test/example/8.2.4.0-RC1
/foo/bar/test/example/8.2.4.0-RC2
/foo/bar/test/example/8.2.4.0-RC10

答案 2 :(得分:-1)

我发现了一个完全不同于@ mklement0建议我的解决方案。

#!/bin/bash

echo "Enter a version :"
read VERSION

while read line; 
do

  find $line -type d | grep $VERSION | sort -n >> outfile.txt

  grep '.*-alpha[0-9]' outfile.txt | sort -n >> outfile2.txt 
  grep '.*-beta-ri[0-9]' outfile.txt | sort -n >> outfile2.txt 
  grep '.*-beta-rs[0-9]' outfile.txt | sort -n >> outfile2.txt 
  grep '.*-RC[0-9]' outfile.txt | sort -n >> outfile2.txt   
  rm outfile.txt 

done <whatever.txt

outfile2.txt的内容:

/foo/bar/test/example/8.2.4.0-alpha10
/foo/bar/test/example/8.2.4.0-alpha8
/foo/bar/test/example/8.2.4.0-alpha9
/foo/bar/test/example/8.2.4.0-beta-ri1
/foo/bar/test/example/8.2.4.0-beta-ri2
/foo/bar/test/example/8.2.4.0-beta-rs1
/foo/bar/test/example/8.2.4.0-beta-rs2
/foo/bar/test/example/8.2.4.0-beta-rs3
/foo/bar/test/example/8.2.4.0-RC1

唯一的问题是alpha10来自alpha8

有任何线索吗?