试试下面的代码:
sar -u|head -5|awk '
BEGIN { hname="'"`hostname -s`"'"; hdt="'"`date +"%d-%b-%Y" `"'" ; OFS="," ;}
$1 ~ /[0-9]/ && $4 ~ /[0-9]/
{ printf( "h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9 );}'
请注意,这是未经测试的,因为我没有sar
程序。如果您粘贴该程序的一些示例输出,我可以测试代码并相应地更新我的答案。
这与您的代码尽可能接近,如果我没有错过任何其他内容,它应该可以工作。您使用的-F
选项没有执行任何操作,因为您没有指定新的字段分隔符( FS
)。请注意,我删除了“搜索”语句{...}
周围的大括号(大括号) 。$1 ~ /[0-9]/ && $4 ~ /[0-9]/
awk
程序由模式和相关操作组成,这些操作针对与模式匹配的那些记录(没有其他选项,每一行被视为一条记录)执行。行动_模式之后用大括号括起来。
因此,您的代码具有三个操作:与特殊BEGIN 模式相关联的初始化,因此在读取任何输入之前执行一次,以及对所有记录(即行)执行的两个操作,因为它们与任何模式无关:第一个评估您的搜索表达式和第二个打印格式化记录。但是请注意,这两个操作没有关联,无论您的搜索表达式评估为真还是假,都会执行打印操作。
要了解您的代码有什么问题,您可以运行以下详细版本:
sar -u|head -5|awk '
BEGIN { hname="'"`hostname -s`"'"; hdt="'"`date +"%d-%b-%Y" `"'" ; OFS="," ;}
{print "search returned "($1 ~ /[0-9]/ && $4 ~ /[0-9]/?"true.":"false.")}
{ printf( "h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9 );}'
这扩展了您的第一个操作以打印搜索表达式的结果,您将看到第二个(即printf
)操作是独立于该结果执行的。
通过删除搜索表达式周围的大括号,您可以使其成为与下一个操作相关联的模式,即那个。这种方式只对那些与您的搜索模式匹配的记录(即行)执行。printf
printf
进一步注意,如果您按照@jaypal singh的建议将外部命令的输出存储在变量中,您的代码将变得更具可读性,以下是通过使用选项初始化变量来实现的:awk
-v
sar -u|head -5|awk \
-v hname="`hostname -s`" \
-v hdt="`date +"%d-%b-%Y"`" \
-v OFS="," \
'
$1 ~ /[0-9]/ && $4 ~ /[0-9]/{
printf( "h=%-15s d=%11s 1=%8s 2=%2s 3=%-3s 4=%6.2f 5=%6.2f 6=%6.2f 7=%6.2f 8=%6.2f 9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9 )
}
'
附录:
正如@jaypal singh所指出的,输出字段分隔符( OFS
) 不会影响prinft
,因此您可能希望在语句中使用逗号 ( ,
) 而不是空格 ( )而不是定义:
printf
OFS
sar -u|awk \
-v hname="`hostname -s`" \
-v hdt="`date +"%d-%b-%Y"`" \
'
$1 ~ /[0-9]/ && $4 ~ /[0-9]/{
printf( "h=%-15s,d=%11s,1=%8s,2=%2s,3=%-3s,4=%6.2f,5=%6.2f,6=%6.2f,7=%6.2f,8=%6.2f,9=%6.2f\n", hname, hdt, $1, $2, $3, $4, $5, $6, $7, $8, $9 )
}
'
请注意,这一次我也head
从管道中删除了,因为您在评论中说这只是出于测试原因而引入,如果它不使用记录号( NR
) 会更好,正如@jaypal singh所建议的那样。