![如何使用管道进行 grep AND 模式](https://linux22.com/image/73625/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E7%AE%A1%E9%81%93%E8%BF%9B%E8%A1%8C%20grep%20AND%20%E6%A8%A1%E5%BC%8F.png)
我写了一段类似于下面的脚本:
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
一些附加信息:
上面的代码在循环中运行,因此每次
$sandbox
都有一个新值。我尝试过
grep -e "${sandbox}.*pset
,但没有解决问题。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
变量,其中包含我们需要匹配的模式,脚本的其余部分匹配变量中的正则表达式awk
并re
打印所需的字段,完成后立即退出。
答案2
grep 必须是 grep 本身。
你可以试试
srvc_location=$(ps -ef| grep ${sandbox}."*pse[t]" | awk '{print $9;exit;}')
grep "*pse[t]"
会 greppset
,但不会pse[t]
pse[t]
作为正则表达式(称为RE)表示字符串pse
,然后是其中的任何一个字符t
,该[]
语法很少用于一个字符,因为确实最容易只提及t
,一般使用grep [abc]oo
谁匹配aoo
,boo
和coo
。当你 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
任何东西时,你应该知道这一点。