我正在尝试从命令输出中提取第二列
例如:
$ sudo /usr/sbin/pvs
PV VG Fmt Attr PSize PFree
/dev/sdc1 vgswap lvm2 a-- 16.00g 0
/dev/sdc2 rootvg lvm2 a-- 48.00g 2.70g
/dev/sde lvm2 --- 32.00g 32.00g
/dev/sdf lvm2 --- 32.00g 32.00g
但问题是某些磁盘未与任何 VG 关联,因此 VG 名称为空,同时像这样提取输出
$ sudo /usr/sbin/pvs | awk '{print $2}'
VG
vgswap
rootvg
lvm2
lvm2
我想像这样提取(如果是空白则为空白)
vgswap
rootvg
答案1
使用专为后处理设计的输出格式,而不是仅供用户使用的默认格式:
$ sudo pvs --reportformat json_std | jq -r '.report[].pv[].vg_name'
vgswap
rootvg
或者要求pvs
以您想要的格式获取您想要的值:
$ sudo pvs --no-headings --config 'log{prefix=""}' -o vg_name
vgswap
rootvg
通过禁用对齐和缩进并更改分隔符,可以使默认输出格式更易于后期处理:
sudo pvs --config $'report{aligned=0 separator="\t"}log{prefix=""}'
只要值不包含换行符或制表符,就可以使其变得简单 TSV,然后您可以使用以下命令进行后期处理:
假设列始终vg_name
具有VG
标题:
mlr --tsvlite --headerless-csv-output cut -f VG
或者:
awk 'NR==1{for (i = i; i <= NF; i++) h[$i]=i; next}
{print $ h["VG"]}'
或者,假设该vg_name
列始终是第二列:
awk -F'\t' 'NR > 1 {print $2}'
在不更改输出格式的情况下,假设设备名称不包含换行符或其他控制字符或多字节字符,并且依赖于 VG 名称不能包含空格的事实,您可以将VG
第一个标题行中字符串的偏移量记录为知道在后续行中在哪里查找相应的值:
sudo pvs | awk '
NR == 1 {offset = index($0, "VG"); next}
{$0 = substr($0, offset); sub(/ .*/, ""); print}'
答案2
使用任何 awk:
$ cat file | awk 'NR==1{n=NF; next} {print (NF<n ? "" : $2)}'
vgswap
rootvg
这只是设置n
为输出第一行的字段数,然后如果存在该数量的字段则打印 $2 ,否则打印其余行的空字符串。
您也可以使用 GNU awk ,因为FIELDWIDTHS
您似乎有固定宽度字段在您的输入中:
$ cat file | awk -v FIELDWIDTHS='13 9 *' 'NR>1{print $2}'
vgswap
rootvg
在您的系统上替换cat file
为。sudo /usr/sbin/pvs