首页 > 解决方案 > AWK 命令不能正常连接两个输出

问题描述

我有一个简单的任务,将lsblk命令的输出与df包含安装点的字段上的命令输出连接起来。

示例输出df

$ df -P --exclude={tmpfs,devtmpfs,squashfs,overlay} | sed /^Filesystem/d
/dev/mapper/dockerVG-rootLV    51339744   8118908   40583220      17% /
/dev/mapper/ssdVG-ssdLV       515006720 214044372  274731772      44% /dockerssd
/dev/mapper/hddVG-hddLV      1547129060  83285716 1385183760       6% /dockerhdd
/dev/mapper/hddVG-dockerLV    515006720  76061148  412714996      16% /var/lib/docker

输出lsblk

$ lsblk -n -b --output KNAME,NAME,SIZE,MOUNTPOINT | egrep -v "fd0|ram|loop|sr0|hdc|cdrom|[SWAP]"


sda   sda                   53687091200
sda1  └─sda1                53684994048
dm-3    └─dockerVG-rootLV   53682896896 /
sdb   sdb                 2147483648000
sdb1  └─sdb1              2147482599424
dm-1    ├─hddVG-dockerLV   536866717696 /var/lib/docker
dm-2    └─hddVG-hddLV     1610612736000 /dockerhdd
sdc   sdc                  536870912000
sdc1  └─sdc1               536869863424
dm-0    └─ssdVG-ssdLV      536866717696 /dockerssd

我正在使用 awk;这是我当前的代码:

awk '{ print $1 " " $3 " " $4 " " arr[$4] }
/^\// { arr[$6]=$1 " " $2 " " $3 " " $4 " " $5 }' <<< $(
    df -P --exclude={tmpfs,devtmpfs,squashfs,overlay} |
    sed -e /^Filesystem/d
    lsblk -n -b --output KNAME,NAME,SIZE,MOUNTPOINT |
    egrep -v "fd0|ram|loop|sr0|hdc|cdrom|[SWAP]")

这是我目前得到的输出:

/dev/mapper/dockerVG-rootLV 8118908 40583220
/dev/mapper/ssdVG-ssdLV 214044380 274731764
/dev/mapper/hddVG-hddLV 83285716 1385183760
/dev/mapper/hddVG-dockerLV 76061152 412714992
sda 53687091200
sda1 53684994048
dm-3 53682896896 / /dev/mapper/dockerVG-rootLV 51339744 8118908 40583220 17%
sdb 2147483648000
sdb1 2147482599424
dm-1 536866717696 /var/lib/docker /dev/mapper/hddVG-dockerLV 515006720 76061152 412714992 16%
dm-2 1610612736000 /dockerhdd /dev/mapper/hddVG-hddLV 1547129060 83285716 1385183760 6%
sdc 536870912000
sdc1 536869863424
dm-0 536866717696 /dockerssd /dev/mapper/ssdVG-ssdLV 515006720 214044380 274731764 44%

我不需要这部分输出:

/dev/mapper/dockerVG-rootLV 8118908 40583220
/dev/mapper/ssdVG-ssdLV 214044380 274731764
/dev/mapper/hddVG-hddLV 83285716 1385183760
/dev/mapper/hddVG-dockerLV 76061152 412714992

对我来说,拥有以下内容就足够了:

sda 53687091200
sda1 53684994048
dm-3 53682896896 / /dev/mapper/dockerVG-rootLV 51339744 8118908 40583220 17%
sdb 2147483648000
sdb1 2147482599424
dm-1 536866717696 /var/lib/docker /dev/mapper/hddVG-dockerLV 515006720 76061152 412714992 16%
dm-2 1610612736000 /dockerhdd /dev/mapper/hddVG-hddLV 1547129060 83285716 1385183760 6%
sdc 536870912000
sdc1 536869863424
dm-0 536866717696 /dockerssd /dev/mapper/ssdVG-ssdLV 515006720 214044380 274731764 44%

你能帮我吗,如何划分这个输出?也许在我的 awk 命令中有一些修复?

标签: awksed

解决方案


你的语法很奇怪。可能会按照以下方式重构

awk 'NR == FNR {
    if ($1 ~ /^\//) arr[$6]=$1 " " $2 " " $3 " " $4 " " $5 
    next }
/fd0|ram|loop|sr0|hdc|cdrom|\[SWAP\]/ { next }
{ print $1 " " $3 " " $4 " " arr[$4] }' \
    <(df -P --exclude={tmpfs,devtmpfs,squashfs,overlay}) \
    <(lsblk -n -b --output KNAME,NAME,SIZE,MOUNTPOINT)

Filesystem不匹配^/所以我把它拿出来了。正则表达式[SWAP]不正确;我假设你的意思是从字面上匹配。awk 可以做任何事情egrep并且sed可以做,所以我重构了那些。

这里的牛肉是next里面的第一个条件,避免打印那些行。重构以读取两个单独的文件句柄也使脚本更加惯用,并且希望可以理解。


推荐阅读