如何选择外壳输出的最后一行



嗨,我有一个这样的 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

希望这对您有所帮助。

最新更新