如何从cat输出中读取第一行和最后一行?

dmg*_*mgl 76 shell grep bash sed awk

我有文本文件。任务 - 之后从文件中获取第一行和最后一行

$ cat file | grep -E "1|2|3|4" | commandtoprint

$ cat file
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)

在没有 cat 输出的情况下需要这个(只有 1 和 5)。

~$ cat file | tee >(head -n 1) >(wc -l)
1
2
3
4
5
5
1
Run Code Online (Sandbox Code Playgroud)

也许存在 awk 和更短的解决方案......

cha*_*aos 137

sed解决方案:

sed -e 1b -e '$!d' file
Run Code Online (Sandbox Code Playgroud)

stdinif读取时看起来像这样(例如ps -ef):

ps -ef | sed -e 1b -e '$!d'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1931  1837  0 20:05 pts/0    00:00:00 sed -e 1b -e $!d
Run Code Online (Sandbox Code Playgroud)

头尾解决方案:

(head -n1 && tail -n1) <file
Run Code Online (Sandbox Code Playgroud)

当数据来自命令 ( ps -ef) 时:

ps -ef 2>&1 | (head -n1 && tail -n1)
UID        PID  PPID  C STIME TTY          TIME CMD
root      2068  1837  0 20:13 pts/0    00:00:00 -bash
Run Code Online (Sandbox Code Playgroud)

awk解决方法:

awk 'NR==1; END{print}' file
Run Code Online (Sandbox Code Playgroud)

还有管道示例ps -ef

ps -ef | awk 'NR==1; END{print}'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1935  1837  0 20:07 pts/0    00:00:00 awk NR==1; END{print}
Run Code Online (Sandbox Code Playgroud)

  • `head &amp;&amp; tail` 真的适合你吗?`seq 10 | (head -n1 &amp;&amp; tail -n1)` 仅打印 `1`。 (10认同)
  • 谢谢!这是最好的答案,因为我不能做`(head -n1 file;tail -n1 file)` 我有非常大的命令和管道作为最后一个符号。所以`| sed '1p;$!d'` 更短的一个。 (2认同)
  • @DavidConrad,详细说明混乱所说的内容,“-e 1b”——在第一行,分支到 sed 脚本的末尾,此时隐式“打印”发生。如果输入只有一行长,则 sed 结束。否则,删除除最后一行之外的所有行。在最后一行,隐含的“打印”再次发生。 (2认同)

sch*_*iba 27

sed -n '1p;$p' file.txt 将打印 file.txt 的第一行和最后一行。

  • 请注意,如果输入只有一行,则会打印两次。如果你不想,你可能更喜欢 `sed -e 1b -e '$!d'`。 (10认同)

gni*_*urf 10

一个有趣的纯 Bash?4 种方式:

cb() { (($1-1>0)) && unset "ary[$1-1]"; }
mapfile -t -C cb -c 1 ary < file
Run Code Online (Sandbox Code Playgroud)

在此之后,您将拥有一个数组,ary其中第一个字段(即 index 0)是 的第一行file,其最后一个字段是 的最后一行file。回调cb(如果您想删除数组中的所有行,则可选)取消设置所有中间行,以免使内存混乱。作为免费的副产品,您还将获得文件中的行数(作为数组的最后一个索引 +1)。

演示:

$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' {a..z})
$ declare -p ary
declare -a ary='([0]="a" [25]="z")'
$ # With only one line
$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' "only one line")
$ declare -p ary
declare -a ary='([0]="only one line")'
$ # With an empty file
$ mapfile -t -C cb -c 1 ary < <(:)
declare -a ary='()'
Run Code Online (Sandbox Code Playgroud)


don*_*sti 8

有了sed你可以delete行,如果1ST一个AND NOT洛杉矶$t的一。
使用!NOT(否定)的条件和X{Y..}结构结合X Y条件:

cmd | sed '1!{$!d;}'
Run Code Online (Sandbox Code Playgroud)

或者您可以使用一个范围 - 从2nd 到 la $t - 并删除该范围内除 la $t 行之外的所有行:

cmd | sed '2,${$!d;}'
Run Code Online (Sandbox Code Playgroud)


小智 7

使用 Perl:

$ seq 10 |  perl -ne 'print if 1..1 or eof'
1
10
Run Code Online (Sandbox Code Playgroud)

以上打印seq 10via the 输出中的第一项if 1..1,而or eof也将打印最后一项。

  • 你能解释一下这是如何工作的吗?请避免在没有解释他们做什么和如何做的情况下给出这样的单行答案。 (3认同)

小智 5

没有猫:

$ cat file |tee >(head -n1) >(tail -n1) >/dev/null
1
5
Run Code Online (Sandbox Code Playgroud)

或者

$ (head -n1 file;tail -n1 file)
1
5
Run Code Online (Sandbox Code Playgroud)

  • 在第一个中,不保证行的顺序。 (8认同)

gle*_*man 5

$ seq 100 | { IFS= read -r first; echo "$first"; tail -1; }
1
100
Run Code Online (Sandbox Code Playgroud)