如何使用管道进行 grep AND 模式

如何使用管道进行 grep AND 模式

我写了一段类似于下面的脚本:

srvc_location=`ps -ef| grep '${sandbox}.*pset' | head 1 | awk {print $9}`
echo "SERVICE LOC : "$srvc_location

但奇怪的是,$srvc_location大多数时候这个问题都得到了解决,但有时却没有通过以下消息得到解决:

SERVICE LOC : strrosdev_silo1_int.*pset

一些附加信息:

  1. 上面的代码在循环中运行,因此每次$sandbox都有一个新值。

  2. 我尝试过 grep -e "${sandbox}.*pset ,但没有解决问题。

  3. grep我可以通过使用两个, 来解决问题grep $sandbox |grep pset,但我想只使用一个带有模式的 , 。

为什么它会这样?

答案1

代码失败的原因之一是您在变量周围的表达式中使用单引号'...'而不是双引号。"..."grep

用这个代替

srvc_location=$(ps -ef| grep "${sandbox}.*pset" | head -1 | awk '{print $9}')
echo "SERVICE LOC : $srvc_location"

实际上,很少需要结合head,awk像这样,因为awk可以这样做:

srvc_location=$(ps -ef| grep "$sandbox.*pset" | awk '{print $9; exit}')

甚至这个,不太清楚但也合并在grep其中:

srvc_location=$(ps -ef| awk -v sb="$sandbox" 'BEGIN { re = sb ".*pset" } $0 ~ re { print $9; exit}')

这里我们使用了 的几个功能awk。我们定义一个awk名为 的变量sb,它采用 shell 变量 的值$sandbox。该BEGIN块定义了一个awk变量,其中包含我们需要匹配的模式,脚本的其余部分匹配变量中的正则表达式awkre打印所需的字段,完成后立即退出。

答案2

grep 必须是 grep 本身。

你可以试试

srvc_location=$(ps -ef| grep ${sandbox}."*pse[t]" | awk '{print $9;exit;}')
  • grep "*pse[t]"会 grep pset,但不会pse[t]

    pse[t]作为正则表达式(称为RE)表示字符串pse,然后是其中的任何一个字符t,该[]语法很少用于一个字符,因为确实最容易只提及t,一般使用grep [abc]oo谁匹配aooboocoo

    当你 grep用固定的字符串a 的结果ps,您还 grep grep 进程及其参数。在上面的技巧中,REpse[t]计算结果pset与固定字符串 不匹配pse[t]


编辑:高尔夫代码

srvc_location=$(ps -ef| grep -m 1 -o ${sandbox}."*pse[t]")
  • -m 1只打印一个匹配的图案
  • -o只输出matchint模式

答案3

该命令最好写成

srvc_location=$(ps -ef| grep '${sandbox}.*pset' | head 1 | awk {print $9})

您的版本将把 srvc_location 设置为值 ps,然后尝试执行-ef并尝试将其输出传送到grep等。

答案4

到目前为止,只需添加一件事即可:

命令

head 1

将输出第一个10文件的行数命名的 1, 和会完全忽略stdin

您想要的(对于命令的该部分)是:

head -1

它将从标准输入输出第一行(仅一行)。

或者,当然,只需使用awk已经建议的功能。但当你使用head任何东西时,你应该知道这一点。

相关内容