有时我需要向数据库添加更多磁盘;为此,我需要列出磁盘以查看哪些磁盘已存在。
问题是输出总是排序为 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 打印字段。然后使用sort
2 个制表符分隔的字段,然后删除制表符。通过管道连接以避免 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
-n
print
print
第一个一行中,\d
是任意数字 (0-9),\D
是任意非数字。这些模式中的每一个都重复 0 次或多次(使用*
)。这两个模式使用括号捕获并作为LIST
两个字段中的一个返回,这两个字段在 TAB 上连接并打印。
第二个 Perl 单行代码只是删除第一个 TAB 查找内容(空字符串)并打印该行。
对于sort
2 个字段,使用以下选项:
-k1,1
:按 ASCII 方式对字段 1 进行排序。然后:
-k2,2n
:如果字段 1 相同,则按字段 2 的数字排序(-n
选项)。
请注意,字段编号重复两次(例如,1,1
),以防止对行的其余部分进行排序并将排序限制为仅此列编号。