![如何从文件中 grep 一个以模式开头并以模式结尾的字符串](https://linux22.com/image/945224/%E5%A6%82%E4%BD%95%E4%BB%8E%E6%96%87%E4%BB%B6%E4%B8%AD%20grep%20%E4%B8%80%E4%B8%AA%E4%BB%A5%E6%A8%A1%E5%BC%8F%E5%BC%80%E5%A4%B4%E5%B9%B6%E4%BB%A5%E6%A8%A1%E5%BC%8F%E7%BB%93%E5%B0%BE%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我有这个脚本:
#!/bin/bash
user=datab-admin-role
allusers="datab-admin-111role datab-admin-112role datab-admin-113role "
if(...)
then..
...
我只想 在变量中grep 第一次出现的以 开头datab
和以 结尾的字符串。role
我正在尝试的是:
sed -n '/datab/,/role/p' filename
但是它返回所有带有 datab 的字符串,并且它返回的内容如下:
user=datab-admin-role
我希望它仅返回datab-admin-role
并将其分配给一个变量。
答案1
我会使用 grep 来实现这个:
grep -o -m 1 'datab[A-Za-z0-9-]*role' filename
该-o
标志意味着仅返回与模式匹配的行的部分,而不是整行。
该-m 1
标志表示仅返回第一次出现的情况。
该模式是以 开头的任何内容,datab
后面仅跟有字母、数字和连字符,然后role
是 ,这就是我认为您想要的,因为您不只是想要一个包含空格或标点符号或其他内容的较长字符串。
分配给变量:
myvar="$(grep -o -m 1 'datab[A-Za-z0-9-]*role' filename )"
sed
但我确信也有办法做到这一点。
答案2
我可能会用发布的 grep 解决方案不过你可以在 sed 中使用捕获组。
在 sed 中,/pattern1/,/pattern2/
处理线路范围在匹配的模式之间 - 如果你想在一行上匹配模式,你需要类似
sed -n '/.*\(datab.*role\).*/{s//\1/p;q;}' filename
其中\(
和\)
定义一个捕获组,并\1
反向引用它,省略任何前导.*
和尾随.*
字符以模拟 grep 的-o
或--only-matching
flag (并且我们q
在第一个匹配后 uit 以模拟 grep 的-m1
)。
或者使用 GNU sed
sed -En 's/.*(datab.*role).*/\1/p;T;q' filename
(此处T
分支超出范围q
直到s
成功)。
如果有必要,您可以更改(datab.*role)
为(datab[A-Za-z0-9-]*role)
进行更具限制性的匹配。
答案3
perl 方法:
$ perl -lne 'if(/datab.+?role/){print $&; exit}' file
datab-admin-role
为每个调用添加-l
一个换行符print
,并从每个输入行中删除尾随的换行符。-n
意思是“逐行读取输入文件并将给出的脚本应用于-e
每一行”。
脚本本身会尝试匹配datab
最短的可能字符串 ( .+?
),直到找到第一个role
。如果找到,我们将打印匹配的内容 (特殊变量$&
) 并退出。
要存储在变量中,只需执行以下操作:
var=$(perl -lne 'if(/datab.+?role/){print $&; exit}' file)