[英]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
唯一的錯誤是alpha10
在alpha8
之前
有什么線索嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.