it-swarm.cn

排序,但标题行保持在顶部

我从一个程序中获得输出,该程序首先产生一行,该行是一堆列标题,然后是一串数据。我想剪切此输出的各个列,并查看根据各个列排序的内容。如果没有标题,则通过sort-k选项与cutawk一起查看列的子集,即可轻松完成剪切和排序。但是,这种排序方法将列标题与其余的输出行混合在一起。有没有一种简单的方法可以将标题保留在顶部?

63
jonderry

窃取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"
    "[email protected]"
}

现在我可以做:

$ 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
66
Mikel

您可以使用bash这样将标题保留在顶部:

command | (read -r; printf "%s\n" "$REPLY"; sort)

或用Perl来做:

command | Perl -e 'print scalar (<>); print sort { ... } <>'
41
Andy

我发现 一个不错的awk版本 可以在脚本中很好地工作:

awk 'NR == 1; NR > 1 {print $0 | "sort -n"}'
30
Michael Kuhn

骇人但有效:加0到所有标题行和1到所有其他行,然后再排序。排序后去除前缀。

… |
awk '{print (NR <= 2 ? "0 " : "1 ") $0}' |
sort -k 1 -k… |
cut -b 3-
5

这是一些不可思议的Perl线路噪音,您可以通过它传递输出以对所有内容进行排序,但将第一行保持在顶部:Perl -e 'print scalar <>, sort <>;'

4
Ryan C. Thompson

我尝试了command | {head -1; sort; }解决方案,并可以确认确实搞砸了 --head从管道中读取了多行,然后仅输出第一个。因此,剩下的输出,即head未读的结果,传递给sort--从第2行开始的输出!

结果是您丢失了命令输出开头的行(和一个不完整的行!)(除非您仍然有第一行)-通过在wc在上述管道的末尾-但是如果您不知道这一点,将很难找到它!我花了至少20分钟的时间来弄清楚为什么在解决输出之前在输出中有部分行(前100个字节左右被截断)。

我最终做的是,它工作得很好,不需要两次运行该命令,它是:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile
sed 1d $myfile | sort

rm $myfile

如果需要将输出放入文件中,可以将其修改为:

myfile=$(mktemp)
whatever command you want to run > $myfile

head -1 $myfile > outputfile
sed 1d $myfile | sort >> outputfile

rm $myfile
2
Wildcard

我认为这是最简单的。

ps -ef | ( head -n 1 ; sort )

或者这可能更快,因为它不会创建子Shell

ps -ef | { head -n 1 ; sort ; }

其他很酷的用途

标题行后的随机行

cat file.txt |  ( head -n 1 ; shuf )

标题行后的反向行

cat file.txt |  ( head -n 1 ; tac )
1
user2449151
command | head -1; command | tail -n +2 | sort
0
Sarva

我来到这里为命令w寻找解决方案。此命令显示谁登录的详细信息以及他们正在做什么。

为了显示排序的结果,但标题保持在顶部(标题有两行),我选择了:

w | head -n 2; w | tail -n +3 | sort

显然,这会两次运行命令w,因此可能并不适合所有情况。但是,其优点是很容易记住。

请注意,tail -n +3的意思是“显示从3号开始的所有行”(请参阅​​man tail了解详情。

0
Robert

简单明了!

<command> | head -n 1; <command> | sed 1d | sort <....>
  • sed nd --->'n'指定行号,'d'代表删除。
0
Jatsui