尝试对两个括号之间的所有内容进行正则表达式处理{
}
。类似问题
正则表达式匹配任何字符,包括换行符 - Vi & Vim,但我不明白提供的解决方案。
使用:
nft list table inet filter
返回此:
table inet filter {
set ipaddr {
type ipv4_addr
flags timeout
elements = { 192.168.1.102, 192.168.1.119,
192.168.1.133, 192.168.1.134 }
}
}
我想使用正则表达式来获取元素内的所有内容,例如:
192.168.1.102,192.168.1.119,192.168.1.133,192.168.1.134
我以为我可以使用grep
,但只要能用就很好了。
答案1
链接中的信息特定于 vi/vim 正则表达式,并不直接适用于 grep。
grep 中的等效项可能是使用 perl 兼容正则表达式 (PCRE),其s
修饰符告诉正则表达式引擎在“任何字符”集中包含换行符.
(通常.
意味着任何字符除了新队)。
例如pcregrep
使用M
ultiline 标志:
$ pcregrep -Mo '(?s)elements = {.*?}' yourexample
elements = { 192.168.1.102, 192.168.1.119,
192.168.1.133, 192.168.1.134 }
您可以在常规 GNU grep 中强制执行类似的操作,方法是使用标志-z
作为代理-M
:
grep -zPo '(?s)elements = {.*?}'
如果您也想格式化匹配的文本,我会切换到 perl 适当的 ex。
$ perl -00nE 'say $1 =~ s/\n\s*/ /r if m/elements = {(.*?)}/s' yourdata
192.168.1.102, 192.168.1.119, 192.168.1.133, 192.168.1.134
答案2
另一个解决方案是:
nft list table inet filter | sed -zne 's/^.*elements = { //; s/ }.*$//; s/[ \n]\+/ /gp'
在这里我们使用:
-z
将整个输入视为一行的选项。-n
抑制模式空间自动打印的选项。
在脚本部分:
- 第一个脚本(
s/^.*elements = { //;
)删除从开头到elements = {
输入的字符串的第一部分。 - 第二个脚本(
s/ }.*$//;
)删除从 开始}
直到输入结束的其余部分。 - 第三个脚本(
s/[ \n]\+/ /gp
)将任何多个空格(换行符和空格符)g
全局替换为单个空格字符并p
打印结果。
答案3
这是一个sed
解决方案(感谢@FedonKadifeli 关于缩短我的初始命令的建议):
nft list table inet filter | sed -zn 's/.*elements = { \([0-9,\. \n]*\) }.*/\1/; s/\n//; s/ \+/ /p'
我们将输出通过管道传输nft list table inet filter
到一系列sed
命令:
s/.*elements = { \([0-9,\. \n]*\) }.*/\1/
选择elements
括号之间的任何内容。s/\n//
删除选择中的所有换行符。s/ \+/ /p
用一个空格替换多个空格。
从man sed
:
-n, --quiet, --silent
suppress automatic printing of pattern space
-z, --null-data
separate lines by NUL characters
输出为:
192.168.1.102, 192.168.1.119, 192.168.1.133, 192.168.1.134
答案4
您可以使用 bash 正则表达式语句。
$ [[ $(nft list table inet filter) =~ \
elements[\ =]+\{([^}]*) ]] && echo "${BASH_REMATCH[1]//[[:space:]]/}"