检查命令输出中的字段是否为空

时间:2018-04-20 07:50:08

标签: linux shell awk centos lsof

我正在执行命令

E

命令的输出:

lsof -nPs

如果字段值为空,有没有办法将虚拟值设置为字段值?

代表:

COMMAND     PID   TID    USER   FD      TYPE             DEVICE      SIZE       NODE NAME
systemd       1          root  cwd       DIR              253,0      4096        128 /
docker-co 10166 10173    root    0r      CHR                1,3                 1028 /dev/null
sshd      10592          root  mem       REG              253,0    263800   67353392 /usr/lib64/security/pam_systemd.so
sshd      10592          root  DEL       REG                0,5             21551641 /dev/zero
sshd      10592          root    0u      CHR                1,3                 1028 /dev/null

注意:

  • 主要问题是TID字段,它出现在CentOs 7中,但不在Centos 6中。
  • 我正在制作一个可以同时适用于Os的脚本。 (CentOs 6和CentOs 7)
  • 我想要实现的是,每当TID出现在输出中时,只需忽略它。
  • 我认为实现目标的方法是,检查输出中的字段数(使用awk的NF),并检查字段数是否为10 =>忽略TID。
  • 为什么不起作用? :可能存在SIZE和DEVICE的值为空的情况。在这种情况下,字段数将小于10,因此当TID非空时,脚本将无法处理该方案。所以,它无法忽视它。

因此,如果有办法将虚拟值放入空字段,则可以解决问题。

如果值为空,是否可以放置虚拟标记。像null一样,所以如果值为null,我可以检查并忽略。

对此的任何其他解决方案都将是一个很大的帮助。

谢谢。

1 个答案:

答案 0 :(得分:0)

这(使用GNW awk for FIELDWIDTHS)将您的文件从固定宽度字段转换为制表符分隔值,因此您实际上不需要将任何空字段设置为" null&#34字符串;能够识别空字段以进行任何进一步处理(例如,导入Excel电子表格或使用随后使用制表符分隔字段的脚本进行解析):

$ cat tst.awk
BEGIN {
    FIELDWIDTHS="10 6 6 8 5 10 19 10 11 999"
    OFS="\t"
}
{
    for (i=1; i<=NF; i++) {
        gsub(/^ *| +$/,"",$i)
    }
    print
}

$ awk -f tst.awk file
COMMAND PID     TID     USER    FD      TYPE    DEVICE  SIZE    NODE    NAME
systemd 1               root    cwd     DIR     253,0   4096    128     /
docker-co       10166   10173   root    0r      CHR     1,3             1028    /dev/null
sshd    10592           root    mem     REG     253,0   263800  67353392        /usr/lib64/security/pam_systemd.so
sshd    10592           root    DEL     REG     0,5             21551641        /dev/zero
sshd    10592           root    0u      CHR     1,3             1028    /dev/null

如果你真的觉得你想要&#34; null&#34;用空格填充的值和字段然后它只是一个微小的调整来设置$ i如果它为空并将输出传递给列进行格式化(或者如果你愿意,你可以在awk中格式化它):

$ cat tst.awk
BEGIN {
    FIELDWIDTHS="10 6 6 8 5 10 19 10 11 999"
    OFS="\t"
}
{
    for (i=1; i<=NF; i++) {
        gsub(/^ *| +$/,"",$i)
        if ($i == "") {
            $i = "null"
        }
    }
    print
}

$ awk -f tst.awk file | column -t -s$'\t'
COMMAND    PID    TID    USER  FD   TYPE  DEVICE  SIZE    NODE      NAME
systemd    1      null   root  cwd  DIR   253,0   4096    128       /
docker-co  10166  10173  root  0r   CHR   1,3     null    1028      /dev/null
sshd       10592  null   root  mem  REG   253,0   263800  67353392  /usr/lib64/security/pam_systemd.so
sshd       10592  null   root  DEL  REG   0,5     null    21551641  /dev/zero
sshd       10592  null   root  0u   CHR   1,3     null    1028      /dev/null

或准确保留原始空白区域和字段对齐:

$ cat tst.awk
BEGIN {
    FIELDWIDTHS="10 6 6 8 5 10 19 10 11 999"
}
{
    out = ""
    for (i=1; i<=NF; i++) {
        if ($i !~ /\S/) {
            sub(/ {5}$/,"null ",$i)
        }
        out = out $i
    }
    print out
}

$ awk -f tst.awk file
COMMAND     PID   TID    USER   FD      TYPE             DEVICE      SIZE       NODE NAME
systemd       1  null    root  cwd       DIR              253,0      4096        128 /
docker-co 10166 10173    root    0r      CHR                1,3      null       1028 /dev/null
sshd      10592  null    root  mem       REG              253,0    263800   67353392 /usr/lib64/security/pam_systemd.so
sshd      10592  null    root  DEL       REG                0,5      null   21551641 /dev/zero
sshd      10592  null    root    0u      CHR                1,3      null       1028 /dev/null

如果您没有使用FIELDWIDTHS的GNU awk,您可以在任何带有循环调用substr()的awk中执行相同操作。