我从一个程序中获取输出,该程序首先生成一行,该行是一堆列标题,然后是一堆数据行。我想剪切此输出的各个列,并查看它根据各个列排序。如果没有标题,则可以通过-k
选择列的子sort
集cut
或awk
查看列的子集轻松完成剪切和排序。但是,这种排序方法将列标题与其余输出行混合在一起。有没有一种简单的方法可以将标题保持在顶部?
答案1
窃取 Andy 的想法并将其变成一个函数,这样更容易使用:
# print the header (the first line of input)
# and then run the specified command on the body (the rest of the input)
# use it in a pipeline, e.g. ps | body grep somepattern
body() {
IFS= read -r header
printf '%s\n' "$header"
"$@"
}
现在我可以做:
$ ps -o pid,comm | body sort -k2
PID COMMAND
24759 bash
31276 bash
31032 less
31177 less
31020 man
31167 man
...
$ ps -o pid,comm | body grep less
PID COMMAND
31032 less
31177 less
答案2
您可以使用 bash 将标题保留在顶部,如下所示:
command | (read -r; printf "%s\n" "$REPLY"; sort)
或者用 perl 来做:
command | perl -e 'print scalar (<>); print sort { ... } <>'
答案3
我发现一个不错的 awk 版本在脚本中效果很好:
awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'
答案4
命令pee
来自更多实用程序专为此类任务而设计。
例子:
要保留一个标题行,并对第二(数字)列进行排序stdin
:
<your command> | pee 'head -n 1' 'tail -n +2 | sort -k 2,2 -n'
解释:
pee
:将 stdin 通过管道传输到一个或多个命令并连接结果。
head -n 1
:打印标准输入的第一行。
tail -n +2
:从标准输入打印第二行及以下行。
sort -k 2,2 -n
:按第二列数字排序。
测试:
printf "header\na 1\nc 3\nb 2\n" | pee 'head -n 1' 'tail -n +2 | sort -k 2,2 -n'
给出
header
a 1
b 2
c 3