簡體   English   中英

排序find命令以遵守Unix中的自定義順序

[英]Sort a find command to respect a custom order in Unix

我有一個腳本(通過find )輸出文件路徑,我想根據非常特定的自定義邏輯對其進行排序

  • 第一個排序鍵:我希望根據我提供的鍵列表使用自定義排序對第二個(如果存在的話)和第三個-分隔的字段進行排序-但不包括數字后綴。
    在下面的示例輸入中,鍵列表為:
    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

使用我對原始問題的答案的變體形式:

./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值之后排序,並使用它們之間的字母排序。

盡管這與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

我發現了與@ 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

唯一的錯誤是alpha10alpha8之前

有什么線索嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM