【问题标题】:Grep-ing while keeping first line保留第一行的同时进行grep
【发布时间】:2015-03-21 01:30:32
【问题描述】:

我试图理解这种特殊的行为。基本上,我正在尝试 grep 命令的输出,同时仍保留第一行/标题。我在这里先向您的帮助表示感谢。

成功案例

ps -ef | { head -1; grep bash; }

输出:

UID        PID  PPID  C STIME TTY          TIME CMD
username  1008     1  0 Jan21 tty1     00:00:00 -bash
username  1173  1008  0 Jan21 tty1     00:00:00 -bash

失败案例

 ls -tlrh / | { head -1; grep tmp; }

输出:

total 100K

(即:它忽略 /tmp 文件夹)

【问题讨论】:

  • 到目前为止,两个答案都解决了问题,但我认为 OP 想了解为什么一个案例成功而另一个案例失败。这两个答案无法解释。我通过添加几个标签来编辑问题。我做组命令然后管道到另一个 cmd,但没有测试管道到命令组。有趣的问题+1 想知道原因。顺便说一句,如果您检查第二个失败案例echo $?,则返回值为1,但是通过将2>&1 添加到所有命令中,我看不到任何错误消息...
  • 我无法在我的系统上复制它...是否可能存在某种权限问题阻止非 root 用户读取 / 或其他什么?
  • @Kent。感谢您的编辑,是的,我想了解其背后的原因。我注意到它不仅限于这两个命令。我使用了 check_mk 监控,'cmk -D' 输出也给出了成功的结果。

标签: linux bash shell grep pipe


【解决方案1】:

@Jotne 的答案更好,但有时您可以使用 grep -E 如果您知道第一行中的某些内容,那么您可以使用管道符号搜索那个或您想要的其他内容来表达交替:

ps -ef | grep -E "UID|bash"

输出

UID   PID  PPID   C STIME   TTY           TIME CMD
502   510   509   0  8:01am ttys000    0:00.08 -bash
502 48806   510   0 10:18am ttys000    0:00.00 grep -E UID|bash

【讨论】:

  • 感谢您的回答。是的,这是我一直在使用的方式,但我不太喜欢它,因为我需要先查看输出才能获得线路。
  • 这实际上非常适合休闲使用。大多数时候,你想要快速而不是输入太多
【解决方案2】:

尝试使用awk,eks:

ls -tlrh / | awk 'NR==1; /tmp/'

这将打印行号1tmp

NR==1;打印行号1
/tmp/打印所有包含tmp的行

【讨论】:

  • 感谢您的解决方案。它非常优雅,我喜欢它。但是,我不能将其标记为答案,因为它没有解释这种特殊行为的原因。
【解决方案3】:

这不起作用的原因是两个进程中的第一个(head -n1)读取的内容多于输出的内容。它吃掉了 ls 的输出,没有给 grep 进程留下任何东西; ps 逐行创建其输出。

解决此问题的正确方法是为每个需要它的进程复制 STDOUT,如此处所述

redirect COPY of stdout to log file from within bash script itself

然而,在这里只需逐行输入阅读脚本就足够了,以避免任何缓冲问题:

ls -ltrh / | while { read a; } do echo $a; done | { head -n 1; grep tmp; }

但是,这意味着 grep 看不到行,head 已消耗。

【讨论】:

  • 感谢您的信息。我尝试运行该命令,但仍然得到与我运行的原始命令相同的输出。或者,我错过了什么?
  • 这对我有用;但是,如果它不适合您,您应该坚持提到的规范解决方案(重复标准输出)。这将是 Zoltán Nagy 下面概述的一个 - tee >(command >&3) 将输出复制到第一个命令,将此命令输出发送到 fd 3,然后 grep 使用 stdin,最后 fd 3 的输出被重定向到标准输出。
【解决方案4】:

嗯.. 这适用于...但只是为了注意一个非常复杂的解决方案

(ps aux | tee >(head -n1 >&3 ) | grep bio >&3 ) 3>&1

这并不像我想要的那么好,fd3 的使用让它变得很奇怪

注意:理论上 grep 输出甚至可能在标题之前

【讨论】:

    【解决方案5】:

    纯 sed 解决方案 ;)

    ps aux|sed '1p;/kwork/p;d'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-05
      • 2013-09-02
      • 2017-10-23
      • 2021-12-25
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 2016-07-11
      相关资源
      最近更新 更多