如何选择shell输出的最后一行

Tej*_*iya 6 bash shell awk sed

你好,我有一个像这样的 shell 命令。

s3=$(awk 'BEGIN{ print "S3 bucket path" }
 /Executing command\(queryId/{ sub(/.*queryId=[^[:space:]]+: /,""); q=$0 }
 /s3:\/\//{ print "," $10 }' OFS=',' hive-server2.log)
Run Code Online (Sandbox Code Playgroud)

上面命令的输出是这样的。

echo $s3

2018-02-21T17:58:22,
2018-02-21T17:58:26,
2018-02-21T18:05:33,
2018-02-21T18:05:34
Run Code Online (Sandbox Code Playgroud)

我只想选择最后一行。我需要这样的最后一个输出。

 2018-02-21T18:05:34
Run Code Online (Sandbox Code Playgroud)

我这样尝试过。

awk -v $s3 '{print $(NF)}' 
Run Code Online (Sandbox Code Playgroud)

不起作用。任何帮助将不胜感激。

tri*_*eee 7

一般来说,command | tail -n 1打印输出的最后一行command。但是,您可以重构command其中的形式,以避免生成单独的进程只是为了丢弃其他输出。(相反,您可以替换为。)awk '... { ... print something }'awk '... { ... result = something } END { print result }'awk '/condition/ { print something }' | head -n 1awk '/condition/ { print something; exit }'

如果您已经将结果存储在 shell 变量中s3并且只想打印最后一行,则可以使用参数扩展echo "${s3##*$'\n'}"来实现这一点。$'\n'表示换行符的C 风格字符串是 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 ...
Run Code Online (Sandbox Code Playgroud)

你可能想说的地方

awk -v s3=$'firstvalue\nsecondvalue\nthirdvalue' '{ print $(NF) }'
Run Code Online (Sandbox Code Playgroud)

但即使使用引号,您的脚本也会设置v一些内容,然后告诉 Awk(忽略变量并)处理标准输入,这在命令行上会使其从终端读取。固定脚本可能看起来像

awk 'END { print }' <<<"$s3"
Run Code Online (Sandbox Code Playgroud)

它将变量作为标准输入传递给 Awk,Awk 打印最后一行。“here string”语法<<<value也是 Bash 扩展,不能移植到 POSIX sh