使用shell脚本将两个命令的输出合并到单个表中

时间:2011-11-02 12:59:03

标签: linux shell unix awk

我想显示以下命令的输出,如下所示:

1)

mount | grep -i "/dev/sd*" | awk '{ print NR "\t" $1 "\t" $3 }'

2)

/usr/sbin/smartctl -a /dev/sdb | grep Device: | awk '{print $2 }'

第一个命令显示3列多行,下一个命令显示一列信息。

我希望将两个命令和concat的输出连接起来,并显示为包含多行的4列。请建议。

3 个答案:

答案 0 :(得分:5)

这是paste的用途。使用process substitution使shell将命令视为文件:

paste <(mount | awk 'tolower($0) ~ /\/dev\/sd*/ {print NR "\t" $1 "\t" $3}') \
      <(/usr/sbin/smartctl -a /dev/sdb | awk '/Device:/ {print $2}')

我删除了grep命令,awk很容易做到。

答案 1 :(得分:3)

创建一个命名管道来保存第一个命令的输出:

mkfifo mount_output
mount | grep -i "/dev/sd.*" | awk '{ print NR "\t" $1 "\t" $3 }' > mount_output &

然后使用paste

/usr/sbin/smartctl -a /dev/sdb | grep Device: | awk '{print $2 }' | paste foo -

请注意,awk '{print $2 }'可以简化为cut -d' ' -f2。使用

可以更好地完成临时命名管道
tempd=`mktemp -d`
mkfifo ${tempd}/mount_output

然后rm -rf "$tempd"当不再需要管道时。

答案 2 :(得分:2)

一些想法:

如果你已经在命令行中使用了awk,那么你真的不需要grep。所以你可以这样做:

mount | awk '/\/dev\/sd/ {print NR, $1, $3}'
smartctl -a /dev/sdb | awk '/Device:/ {print $2}'

如果要为每个设备生成一行输出,可以将第一个命令行的输出传递到循环中,然后在循环内运行smartctl,如下所示:

mount | awk '/\/dev\/sd/ {print NR, $1, $3}' | while read nr dev mntpt; do
  echo -e "$nr\t$dev\t$mntpt\t$(smartctl -a $dev | awk '/Device:/ {print $2}')"
done

必须使用-e标记才能将\t识别为标签字符。

相关问题