想象一下命令的输出,例如
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,NUMBER
la $
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 行,上面给出的命令将会失败。
进一步阅读: