嗨,我有一个这样的 shell 命令。
s3=$(awk 'BEGIN{ print "S3 bucket path" }
/Executing command(queryId/{ sub(/.*queryId=[^[:space:]]+: /,""); q=$0 }
/s3:///{ print "," $10 }' OFS=',' hive-server2.log)
上述命令的输出是这样的。
echo $s3
2018-02-21T17:58:22,
2018-02-21T17:58:26,
2018-02-21T18:05:33,
2018-02-21T18:05:34
我只想选择最后一行。我需要这样的最后一个输出。
2018-02-21T18:05:34
我试过这样。
awk -v $s3 '{print $(NF)}'
不工作。任何帮助将不胜感激。
通常,command | tail -n 1
打印command
输出的最后一行。但是,如果command
的形式是awk '... { ... print something }'
则可以重构为awk '... { ... result = something } END { print result }'
以避免生成单独的进程只是为了丢弃其他输出。(相反,您可以将awk '/condition/ { print something }' | head -n 1
替换为awk '/condition/ { print something; exit }'
。
如果您已经在 shell 变量s3
中获得了结果,并且只想打印最后一行,则参数扩展echo "${s3##*$'n'}"
可以执行此操作。表示换行符的 C 样式字符串$'n'
是 Bash 扩展,而用于删除最长匹配前缀的参数扩展运算符##
也不是完全可移植的,因此您应该确保 shebang 行表示#!/bin/bash
,而不是#!/bin/sh
另请注意,不带引号的$s3
是一个错误,除非您特别要求 shell 对值执行空格标记化和通配符扩展。基本上,您应该始终在变量周围使用双引号,除非在几个非常具体的情况下。
您的 Awk命令不起作用有两个原因;首先,如上一段所述,您正在将s3
设置为变量的第一个标记,第二个是您的 Awk 脚本(可能是语法错误)。更详细地说,你基本上在运行
awk -v s3=firstvalue secondvalue thirdvalue '{ print $(NF) }'
^ value ^ script to run ^ names of files ...
你可能想说的地方
awk -v s3=$'firstvaluensecondvaluenthirdvalue' '{ print $(NF) }'
但即使使用引用,您的脚本也会将v
设置为某些内容,然后告诉 Awk (忽略变量并)处理标准输入,这在命令行上会让它从您的终端读取。固定脚本可能如下所示
awk 'END { print }' <<<"$s3"
将变量作为标准输入传递给 Awk,后者打印最后一行。<<<value
"here string"语法也是一个Bash扩展,不能移植到POSIXsh
。
更简单的方法是
command | grep "your filter" | tail -n 1
或直接
command | tail -n 1
你可以试试这个:
echo -e "This is the first line nThis is the second line" | awk 'END{print}'
另一种方法是,从末尾处理文件并在第一次匹配后退出。
tac file | awk '/match/{print; exit}'
嗨,您只需添加echo $s3 | sed '$!d'
即可做到这一点
s3=$(awk 'BEGIN{ print "S3 bucket path" }/Executing command(queryId/{ sub(/.*queryId=[^[:space:]]+: /,""); q=$0 } /s3:///{ print "," $10 }' OFS=',' hive-server2.log)
echo $s3 | sed '$!d'
它将简单地打印:-
2018-02-21T18:05:34
希望这对您有所帮助。