如何排序此输出 1,10,11..2

如何排序此输出 1,10,11..2

有时我需要向数据库添加更多磁盘;为此,我需要列出磁盘以查看哪些磁盘已存在。

问题是输出总是排序为 1,10,11,12...2,20,21...3 等。

如何按照我想要的方式对输出进行排序?简单的sort不行;我也尝试过使用sort -t.. -k.. -n.

我需要排序的示例:

[root@server1 ~]# oracleasm listdisks
DATA1
DATA10
DATA11
DATA12
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
FRA1
FRA10
FRA11
FRA2
FRA3
..
OCR1
OCR2
OCR3
....

我希望如何查看输出:

DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
DATA10
DATA11
DATA12
FRA1
FRA2
FRA3
..
..
FRA10
FRA11
..
OCR1
OCR2
OCR3
....

答案1

你最好的选择是通过管道传输到 GNU sort,并启用 GNUsort--version-sort选项

所以那就是oracleasm listdisks | sort --version-sort

从信息页面

--version-sort’
     Sort by version name and number.  It behaves like a standard sort,
     except that each sequence of decimal digits is treated numerically
     as an index/version number.  (*Note Details about version sort::.)

根据你的输入,它给了我

DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
DATA10
DATA11
DATA12
FRA1
FRA2
FRA3
FRA10
FRA11
OCR1
OCR2
OCR3

答案2

如果sort --version-sort不可用,则分为 2 个字段:字段 1 = 前导非数字,字段 2 = 整数,并在字段之间使用 TAB 打印字段。然后使用sort2 个制表符分隔的字段,然后删除制表符。通过管道连接以避免 I/O 开销。下面是一个示例,其中包含来自 OP 的最小数据片段以及一些附加记录:

echo 1 10 2 11 DATA DATA1 DATA10 DATA11 DATA2 FRA FRA1 FRA10 FRA11 FRA2 | \
    xargs -n1 | \
    perl -lne 'print join "\t", /(\D*)(\d*)/' | \
    sort -k1,1 -k2,2n | \
    perl -pe 's/\t//'

印刷:

1
10
11
2
DATA
DATA1
DATA2
DATA10
DATA11
FRA
FRA1
FRA2
FRA10
FRA11

细节:

Perl 单行代码使用这些命令行标志:
-e: 告诉 Perl 查找内联代码,而不是在文件中。
-n:一次循环输入一行,$_默认将其分配给。 :在内联执行代码之前
-l剥离输入行分隔符(默认在 *NIX 上),并在打印时附加它。 :与 相同,但也是每个循环末尾的行(消除显式)。"\n"
-p-nprintprint

第一个一行中,\d是任意数字 (0-9),\D是任意非数字。这些模式中的每一个都重复 0 次或多次(使用*)。这两个模式使用括号捕获并作为LIST两个字段中的一个返回,这两个字段在 TAB 上连接并打印。

第二个 Perl 单行代码只是删除第一个 TAB 查找内容(空字符串)并打印该行。

对于sort2 个字段,使用以下选项: -k1,1:按 ASCII 方式对字段 1 进行排序。然后:
-k2,2n:如果字段 1 相同,则按字段 2 的数字排序(-n选项)。
请注意,字段编号重复两次(例如,1,1),以防止对行的其余部分进行排序并将排序限制为仅此列编号。

相关内容