如何从 grep 中获取第一个匹配项?

如何从 grep 中获取第一个匹配项?

我正在编写一个脚本,并将其用作变量。

RESULT1=`ps -ef | grep -w "PHANTOM PHA-WRM-EXPIRE"`.

发生的情况是ps列出两个 PID。

[xhobando@noitu TNOITU]$ ps -ef | grep -w "/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE"
phantomxg      7250     1  0 12:15 ?        00:00:01 /usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE

phantomxg    17071     1  0 Oct04 ?        00:05:27 /usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE

我在这里想要实现的是,该grep选项仅查找第一个 PID,而不查找两个 PID。

让我知道这是否有意义。

答案1

使用带有 PCRE 支持的GNU grep(rhel 上的实现):

ps -Ao pid= -o args= |
  grep -Pom1 '^\s*\K\d+(?= \Q/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE\E)'

在哪里

  • -P切换到P类似 erl 的正则表达式(对于\s\K\d(?=...)\Q\E所有类似 perl 的扩展)。
  • -o告诉grep只输出匹配的部分
  • -m1告诉grep只输出第一个匹配行的匹配项。

(所有 3 个标志恰好都是 GNU 扩展,但 GNUgrep恰好是grep在 RHEL 上找到的实现)。

我们不使用ps -fwhich 打印一些我们不关心的字段,而是只选择我们需要的字段(pidargs=后缀是为了删除标题),这样我们就可以更轻松地在命令行上进行匹配。

这里,正则表达式查找^由 0 个或更多 ( *) 个空白字符 ( ) 组成的前导 ( \s) 序列,之后我们标记匹配的开始 ( ),后跟由 1 个或更多 ( ) 个数字 ( )\K组成的序列,前提是它们是后面(向前看运算符,不是匹配的一部分)是一个空格和我们想要的参数(用...引用,以便更容易替换为可能包含正则表达式运算符的其他参数列表)。+\d(?=...)\Q\E

或者只是使用pgrep

pgrep -f '^/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE' | head -n 1

将返回第一个进程的 pid,该进程的 arg 列表(与空格字符连接)以 开头/usr/ud/bin/udt PHANTOM PHA-WRM-EXPIRE

ps请注意,进程在or的输出中默认按 pid 进行数字排序pgrep,并且 pid 数字在达到最大值时会换行,因此您将获得的数字或多或少是随机的。

您可能想要添加一些--sort start_time--sort -start_time,例如ps 按开始时间排序(或添加-o/-n最老的/最新pgrep删除| head -n 1) 如果您想获取最早/最晚启动的进程,而不是保证它是最晚启动的进程被处决udt第一个/最后一个进程可以并且经常在其生命周期中运行多个命令。

如果,正如您对问题的评论所暗示的那样,您想根据当前工作目录选择进程,您可以使用以下zsh方法:

pids=(
  /proc/<1->(e[$'[[ $REPLY/cwd -ef /tdata/PHANTOM &&
    $(<$REPLY/cmdline) = /usr/ud/bin/udt\0PHANTOM\0PHA-WRM-EXPIRE\0* ]]']:t)
)

在这里,查找以/tdata/PHANTOM/usr/ud/bin/udt和作为其前 3 个参数PHANTOM的进程PHA-WRM-EXPIRE

但请注意,除非您的进程具有超级用户权限,否则您只能找到自己进程的工作目录。

相关内容