如何用sed/awk将多行磁盘信息格式化为单行分隔格式?
磁盘多行信息合并为单行并按磁盘拆分的解决方法
问题场景
原始磁盘信息输出(每个磁盘占3行):
0. ct1d0 <INTEL-ADDPF2KX076T9S-2CV1-6.19TB> /pci@4,0/pci8086,347c@4/e,487c@0/disk@1 /dev/chassis/SYS/DBP/HDD0/NVME/disk 1. c2t1d0 <INTEL-ADDPF2KX076T9S-2CV1-6.19TB> /pci@4,0/pci8086,347d@5/apci108e,487c@0/disk@1 /dev/chassis/DBP/HDD1/NVME/disk 2. c3t0d0 <ATA-Min_5300_MAAAD-D3MU-223.57GB> /pci@0,0/pci8e,4872@17/disk@0,0 /dev/chassis/MB/SSDR0/SSD0/disk 3. c4t2d0 <ATA-Min_5300_MTFD-D3MU-223.57GB> /pci@0,0/pci08e,4872@17/disk@2,0 /dev/chassis/SYS/MB/SSDR0/SSD1/disk
期望输出(每个磁盘信息合并为一行,用|分隔):
0. ct1d0 <INTEL-ADDPF2KX076T9S-2CV1-6.19TB>| /pci@4,0/pci8086,347c@4/e,487c@0/disk@1| /dev/chassis/SYS/DBP/HDD0/NVME/disk| 1. c2t1d0 <INTEL-ADDPF2KX076T9S-2CV1-6.19TB>| /pci@4,0/pci8086,347d@5/apci108e,487c@0/disk@1| /dev/chassis/DBP/HDD1/NVME/disk| 2. c3t0d0 <ATA-Min_5300_MAAAD-D3MU-223.57GB>| /pci@0,0/pci108e,4872@17/disk@0,0| /dev/chassis/MB/SSDR0/SSD0/disk| 3. c4t2d0 <ATA-Min_5300_MTFD-D3MU-223.57GB>| /pci@0,0/pci108e,4872@17/disk@2,0| /dev/chassis/SYS/MB/SSDR0/SSD1/disk|
用户尝试的tr命令会把所有内容合并成一行,无法按磁盘拆分,下面是几种可行的解决方法:
方法1:使用awk(推荐,逻辑清晰)
利用行号分组,每3行作为一个磁盘的信息进行合并:
awk 'NR%3==1{line=$0} NR%3==2{line=line "| " $0} NR%3==0{print line "| " $0 "|"}' actual_output
解释
NR%3==1:当行号是3的倍数+1时(即每个磁盘的第一行),将当前行内容存入变量lineNR%3==2:行号是3的倍数+2时(第二行),将当前行追加到line,并用|分隔NR%3==0:行号是3的倍数时(第三行),打印完整的line,追加当前行和末尾的|
方法2:使用sed(单行命令简洁)
通过sed的多行模式读取3行内容,替换换行符为分隔符:
sed -n 'N;N;s/\n/| /g;s/$/|/p' actual_output
解释
N;N:连续执行两次N命令,将当前行、下一行、下下行合并到模式空间中s/\n/| /g:将模式空间内的所有换行符替换为|s/$/|/:在每行末尾添加|-n和p:仅打印处理后的内容
方法3:使用paste + sed
用paste合并3行,再通过sed调整格式:
paste -d'|' - - - < actual_output | sed 's/|/| /g;s/$/|/'
解释
paste -d'|' - - -:从输入读取3行,用|分隔合并为一行sed 's/|/| /g':把所有|替换为|,保证格式一致s/$/|/:在每行末尾添加|
内容的提问来源于stack exchange,提问作者user3132525
相关产品推荐
相关产品推荐

