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

String 按字符串的一部分进行数字排序,string,bash,sorting,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

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

<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新手。

我想到了这句话:

 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
    over,让它进行排序
  • 最后,移除第一列
  • 请注意,我使用了
    \x99
    来分隔第一列和原始数据,它是一个不可见的分隔符,便于以后删除

    • 这里有一个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 }'
      

      awk'BEGIN{split(“,r);n=0}/part=“611-/{x=$0;sub(/.*part=“611-/,”,x);sub(/“*/,”,x);r[++n]=x“,”$0;}END{asort(r);用于(i=1;i
      @Inian OP想要按
      部分
      属性的值排序,其重要性是什么。@肯特:在这种情况下,我的答案实际上符合它,除了
      sbb部分=
      标记的顺序之外?这就够了吗?@Inian如果你将结果与OP预期的结果进行比较,你会发现差异,如果你不能,
      diff
      会帮助您。请注意,每一行都有
      part=
      属性。@Kent:同意,记下答案!OP发布了所需的输出。您的结果看起来与它不一样……也许您想做一些修复……Kent--您完全正确,我会修改……出于某种原因,我没有注意到该部分在xml中并不总是位于第一位。。。。