【问题标题】:How to fetch the 13th and the second last line from the standard output [closed]如何从标准输出中获取第 13 行和倒数第二行 [关闭]
【发布时间】:2021-03-14 04:53:02
【问题描述】:

我有一个将消息输出到标准输出的脚本。 现在我需要从头开始获取第 13 行,并从该输出中获取倒数第二行。

我想知道这是否可以通过单个命令完成,而不是将输出重定向到文件,然后通过它读取几次以提取我的输出。

line 1
line 2
...
line 12
line 13
line 14
...
...
line N-1
line N

我需要获取如下输出:

line 13
line N-1

我有单独的命令来获取我的台词。

获取第 13 行:

scriptoutput | head -n 13

获取 N-1 行:

scriptoutput | tail -n 2 | head -n 1
OR
scriptoutput | sed 'x;$!d'

但是作为标准输出,我无法在一个命令中完成输出。

【问题讨论】:

  • 请在您的问题上尽您的努力,这在 SO 上受到强烈鼓励。
  • 你试过什么?包括您的代码。你遇到了什么问题?
  • 添加了尝试过的命令。
  • 使用scriptoutput | sed 'x;$!d' 调用,sed 将处理脚本scriptoutput输出(因此更好的命名是script 而不是scriptoutput)。不确定是什么问题。另请参阅 awk-way 以读取倒数第二行:unix.stackexchange.com/questions/445340/…

标签: linux bash output line


【解决方案1】:

在读取流时,您永远不知道哪一行是“倒数第二行”,直到您读取实际的最后一行并且流结束。唯一可能的方法,就是一直缓冲上一行,当流结束时,从缓冲区中输出该行。

例如sed:

$ seq 20 | sed -n '13p;${x;p};h'
13
19

等等。使用类似的工具。

seq 20 | awk 'NR==13{print} {last=current; current=$0} END{print last}'

seq 20 | { n=1; while IFS= read -r line; do if ((n++ == 13)); then printf "%s\n" "$line"; fi; previous=$current; current=$line; done && printf "%s\n" "$previous"; }

但您也可以只缓冲整个输出并计算行数并输出倒数第二行....

# with a file
seq 20 > tempfile ; sed -n "13p;$(( $(wc -l < tempfile) - 1 ))p" file
# with memory
seq 20 | { buf=$(cat); sed -n "13p;$(( $(wc -l <<<"$buf") - 1 ))p" <<<"$buf"; }

【讨论】:

  • 谢谢卡米尔库克。 sed 命令正是我想要的。我没有意识到我可以在同一个 sed 命令中提取两条线。再次感谢您。
【解决方案2】:

您能否尝试仅使用显示的示例进行跟踪、编写和测试(因为我没有 OP 的 like 命令,所以我在这里使用cat Input_file 进行测试)。

your_command | tee >(awk 'FNR==13' >&2) | tail -2 | head -1

参考链接https://unix.stackexchange.com/a/560102/188342,如果你的输出很大,那么你也可以在tail 命令之前休眠(几秒钟可能取决于你的输出)。

【讨论】:

  • 谢谢。但是你错过了我遇到的问题。我没有文件中的文本。你的意思是我必须先将我的标准输出放在一个文本文件中,然后再运行你的命令?
  • @pradipti,是的,程序在这里从 Input_file 读取输入。好吧,如果您将该命令的输出放入输出文件中,相信我会更容易,但让我尝试在这里添加另一个解决方案。
  • 谢谢 RavinderSingh13。但似乎这只适用于 cat 命令。尝试使用标准输出并得到错误。 ``` sh: -c: line 0: 意外标记附近的语法错误(' sh: -c: line 0: tee >(awk 'FNR==13' >&2) |尾-2 |头 -1' ```
  • @pradipti,好的,我创建了一个脚本(测试一个以打印文件内容)并像./script.ksh | tee &gt;(awk 'FNR==13' &gt;&amp;2) | tail -2 | head -1 一样运行它,它对我来说很好用。你是如何运行程序的?它是一个提供输出的脚本吗?如果不是很大,那么我们也可以像awk 'FNR==NR{if(FNR==13){print};count++;next} FNR==(count-1)' &lt;(your_script) &lt;(your_script) 那样进行进程替换,但我没有建议,也试试这个?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
相关资源
最近更新 更多