解析linux bash命令输出中的所有列元素

时间:2013-12-04 17:46:01

标签: linux bash string-parsing

我想从命令lsscsi解析输出的列元素。

以下是示例输出

# lsscsi

[0:0:0:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sda
[0:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdb
[1:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdc

示例如果我想要第2列,我的输出应该是

disk
disk
disk

如果cloumn 7,

/dev/sda
/dev/sdb
/dev/sdc

由于

6 个答案:

答案 0 :(得分:3)

像这样使用awk:

awk -v col=7 '{print $col}' file

或打印2列:

awk -v col1=2 -v col2=7 '{print $col1, $col2}' file

或者使其打印多列:

awk -v col='2:7' '{split (col, a, ":"); for (i in a) printf "%s%s", $a[i], OFS; print ""}' file

答案 1 :(得分:2)

不幸的是,就我看来,lsscsi没有提供一致的可解析输出,也没有机会改变字段分隔符。在同一系统上有两个不同的硬盘,设备的列不同!以下代码片段应该让您了解我的意思以及我如何解决它...至少要获得最后一行的设备。要正确获取产品名称和产品版本,也可以使用lssci -c a:b:c:d调用每个设备,然后解析此输出。

lsscsi > /tmp/tmp$$.out
while read line
do
    echo $line
    echo 012345678901234567890123456789012345678901234567890123456789
    echo 0.........1.........2.........3.........4.........5.........
    ID=$(echo $line | cut -c2)
    TYPE=$(echo $line | cut -c16-18)
    PRODUCT=$(echo $line | sed -n 's/.\{18\}\(.*\) *\/dev\/.*/\1/p')
    DEVICE=$(echo $line | sed -n 's/.\{18\}.*\/dev\/\(.*\)/\1/p')
    echo $ID-$TYPE-$DEVICE-$PRODUCT
done

答案 2 :(得分:1)

使用bash你可以使用'read -a',它从标准输入中读取一行,使用IFS字段分隔符进行拆分,默认情况下有空格并填充数组变量,可以引用为$ {array [n]}(零为基础)。

while read -a arr; do
    echo "${arr[1]}"
    echo "${arr[6]}"
done

答案 3 :(得分:1)

简单例子:
(每个例子都是独立的。)

选择第 2 列:

echo -e "[0:0:0:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sda \
  \n[0:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdb \
  \n[1:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdc" \
  | awk '{print $2}'

选择第 7 列:

echo -e "[0:0:0:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sda \
  \n[0:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdb \
  \n[1:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdc" \
  | awk '{print $7}'

选择第 2 列和第 7 列:

echo -e "[0:0:0:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sda \
  \n[0:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdb \
  \n[1:0:1:0]   disk   ATA   VBOX HARDDISK   1.0   /dev/sdc" \
  | awk '{print $2, $7}'

结果:

enter image description here

答案 4 :(得分:0)

没有awk的另一种简单方法:

lsscsi | tr -s ' ' | cut -d' ' -f7

最后一个标志指定列。

答案 5 :(得分:0)

您可能要在lsscsi中使用分隔符:使用perl插入制表符并修剪字段。

lsscsi -g \
| perl -ne 'foreach$c(qw (64 53 47 30 21 13)){
              substr$_,$c,0,"\t"
            };
            s/ *([\t\n])/\1/g;  # trim the fields
            print'

或一根衬纸:

 lsscsi -g|perl -ne 'foreach$c(qw(64 53 47 30 21 13)){substr$_,$c,0,"\t"};s/ *([\t\n])/\1/g;print'