将前 N 行输出移动到末尾,而不使用临时文件

将前 N 行输出移动到末尾,而不使用临时文件

想象一下命令的输出,例如

44444
55555
11111
22222
33333

我怎样才能拉出前 N 行(上面例子中的前两行)并将它们附加到最后,但是不使用临时文件(所以只使用管道)?

11111
22222
33333
44444
55555

类似的东西| sed -n '3,5p;1,2p'(这显然不起作用,因为 sed 不关心命令的顺序)。

答案1

只需将这些行复制到保持缓冲区(然后删除它们),然后在最后一行将保持缓冲区的内容附加到模式空间:

some command | sed '1,NUMBER{           # in this range
H                                       # append line to hold space and
1h                                      # overwrite if it's the 1st line
d                                       # then delete the line
}
$G'                                     # on last line append hold buffer content

gnu sed可以把它写成

some command | sed '1,NUMBER{H;1h;d;};$G'

这是 ol' 的另一种方法ed(它将r的输出some command写入文本缓冲区,然后m跳过1,NUMBERla $t 之后的行):

ed -s <<IN
r ! some command
1,NUMBERm$
,p
q
IN

请注意 - 正如所指出的 - 如果输出少于NUMBER+1 行,这些都会失败。更可靠的方法是(gnu sed语法):

some command | sed '1,NUMBER{H;1h;$!d;${g;q;};};$G'

这个仅删除该范围内的行,只要它们不是最后一行 ( $!d) - 否则它会使用保留缓冲区内容 ( ) 覆盖模式空间g,然后q使用 uits (在打印当前模式空间后)。

答案2

一种awk方法:

cmd | awk -v n=3 '
  NR <= n {head = head $0 "\n"; next}
  {print}
  END {printf "%s", head}'

一项福利超过@don_crissti 的sed方法如果输出有n行或更少,它仍然可以工作(输出行)。

答案3

我已经有了xclip,可以通过以下方式完成:

./a_command | xclip -in && xclip -o | tail -n +3 && xclip -o | head -n 2

这是它的描述:

xclip - command line interface to X selections (clipboard)

NAME
       xclip - command line interface to X selections (clipboard)

SYNOPSIS
       xclip [OPTION] [FILE]...

DESCRIPTION
       Reads from standard in, or from one or more files, and makes the data available as an X selection for pasting into X applications. Prints current X selection to standard out.

       -i, -in
              read text into X selection from standard input or files (default)

       -o, -out
              prints the selection to standard out (generally for piping to a file or program)

答案4

使用 POSIX ex。是的,它用于文件编辑,但它可以在管道中工作。

printf %s\\n 111 222 333 444 555 | ex -sc '1,2m$|%p|q!' /dev/stdin

这可以在管道的开头或结尾添加任意命令,并且工作原理相同。更好的是,考虑到 的存在/dev/stdin,它符合 POSIX 标准。

(我不知道是否/dev/stdin在 POSIX 中指定,但我发现它在 Linux 和 Mac OS X 中都存在。)

sed与使用的保留空间相比,这具有可读性优势- 您只需告诉ex“将这些行移到末尾”,它就会这样做。 (其余命令的意思是“打印缓冲区”和“退出”,它们也相当可读。)

注意:ex如果输入少于 2 行,上面给出的命令将会失败。

进一步阅读:

相关内容