按字符串的一部分进行数字排序

时间:2016-05-04 15:15:36

标签: string bash sorting

我有一个字符串列表,我需要按字符串中的数字排序,例如

<sbb part="611-0068-01" desc="21.6TB HDD  2.5" qty="1"/>
<sbb desc="19.2TB SSD/2.5in" part="611-0112-01" qty="1"/>
<sbb part="611-0112-01" qty="1" desc="19.2TB SSD/2.5in"/>
<sbb part="611-0112-02" desc="19.2TB SSD/2.5in" qty="1"/>
<sbb part="611-0044-01" qty="1" desc="4.8TB SSD  2.5"/>
<sbb part="611-0044-03" desc="4.8TB SSD  2.5" qty="1"/>
<sbb desc="9.6T SSD/2.5in" part="611-0202-01" qty="1" />

我要排序的部分是“611-XXXX-XX”中的XXXX在字符串的引号中,例如611-1111-03的数量低于611-2222-02,因为1111低于2222.

所有字符串都包含此611-XXXX-XX编号,此编号始终以611开头。

此数字可能出现在字符串的开头附近或接近结尾处。不幸的是,字符串中还有另外两组引号,这使得它更加复杂。

此示例的输出:

<sbb part="611-0044-01" qty="1" desc="4.8TB SSD  2.5"/>
<sbb part="611-0044-03" desc="4.8TB SSD  2.5" qty="1"/>
<sbb part="611-0068-01" desc="21.6TB HDD  2.5" qty="1"/>
<sbb desc="19.2TB SSD/2.5in" part="611-0112-01" qty="1"/>
<sbb part="611-0112-01" qty="1" desc="19.2TB SSD/2.5in"/>
<sbb part="611-0112-02" desc="19.2TB SSD/2.5in" qty="1"/>
<sbb desc="9.6T SSD/2.5in" part="611-0202-01" qty="1" />

我正在考虑从611到下一个报价进行搜索。不知道如何编写代码,因为我是一个bash新手。

2 个答案:

答案 0 :(得分:2)

我想出了这句话:

 awk '{t=$0;sub(/.*"611-/,"");sub(/-/,"");sub(/".*/,"");
      print "1"$0"\x99"t}' file|sort -n|sed 's/.*\x99//'  

输出是:

<sbb part="611-0044-01" qty="1" desc="4.8TB SSD  2.5"/>
<sbb part="611-0044-03" desc="4.8TB SSD  2.5" qty="1"/>
<sbb part="611-0068-01" desc="21.6TB HDD  2.5" qty="1"/>
<sbb desc="19.2TB SSD/2.5in" part="611-0112-01" qty="1"/>
<sbb part="611-0112-01" qty="1" desc="19.2TB SSD/2.5in"/>
<sbb part="611-0112-02" desc="19.2TB SSD/2.5in" qty="1"/>
<sbb desc="9.6T SSD/2.5in" part="611-0202-01" qty="1" />

想法是:

  • 提取目标数字,将它们作为第1列(awk部分)
  • 将此内容移交给sort -n,让它进行排序
  • 最后,删除第1列。
  • 请注意,我使用\x99来分隔第一列和原始数据,它是一个不可见的分隔符,以便以后更容易删除。

答案 1 :(得分:0)

这是一个 awk 脚本,其结果比一起管理多个工具的解决方案快得多。

awk 'BEGIN { split("", r); n=0} /part="611-/ { x=$0; sub(/.*part="611-/, "", x); sub(/".*/, "", x); r[++n]=x "," $0; } END { asort(r); for (i=1; i<=n; i++) { x=r[i]; sub(/^[^,]+,/, "", x); print x }'
  1. 过滤感兴趣的部件号
  2. 隔离部件号的相关部分,将其作为分类键放在记录的正面,然后保存到阵列中。
  3. 在END,对数组进行排序,删除排序键并打印。