Regex 使用sed否定部分模式
我想创建一个模式,该模式将查找与该模式匹配的第一个字符串并替换它:Regex 使用sed否定部分模式,regex,bash,sed,regex-negation,regex-group,Regex,Bash,Sed,Regex Negation,Regex Group,我想创建一个模式,该模式将查找与该模式匹配的第一个字符串并替换它: sed -r '0,/^[a-z0-9]* (ALL=\(ALL\) ALL)/s//abc \1\n&/' 我的输入是一个/etc/sudoers文件 我想将^[a-z0-9]*更改为类似/^ALL/但它对我不起作用。我猜您希望从字符串中删除abc,此表达式可能有助于您这样做: ([^abc]*)(.*) 正则表达式 如果这不是您想要的表达式,您可以在中修改/更改表达式 正则表达式电路 您还可以在以下位置可视化您
sed -r '0,/^[a-z0-9]* (ALL=\(ALL\) ALL)/s//abc \1\n&/'
我的输入是一个/etc/sudoers
文件
我想将
^[a-z0-9]*
更改为类似/^ALL/
但它对我不起作用。我猜您希望从字符串中删除abc
,此表达式可能有助于您这样做:
([^abc]*)(.*)
正则表达式
如果这不是您想要的表达式,您可以在中修改/更改表达式
正则表达式电路
您还可以在以下位置可视化您的表达式:
替换文件中的第一个匹配项 如果我理解您的问题,并且您希望在文件中找到与
^[a-z0-9]+ALL=(ALL)ALL
匹配的第一个字符串,并使用扩展正则表达式将^[a-z0-9]+ALL
替换为类似^ABC
,您可以使用:
sed -r '0,/[a-z0-9]+/s/^[a-z0-9]+ ALL(=\(ALL\) ALL.*$)/^ABC\1/'
查看/etc/sudoers
中为wheel
组的成员提供了sudo
访问权限的未注释行,您将有:
$ noc /etc/sudoers
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
因此,要将/etc/sudoers
中的第一个字符串替换为[a-z0-9]+ALL=(ALL)ALL
,您需要:
$ noc /etc/sudoers | sed -r '0,/[a-z0-9]+/s/^[a-z0-9]+ ALL(=\(ALL\) ALL.*$)/^ABC\1/'
^ABC=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
按评论编辑
在你的评论中,你说你想找到“ALL=(ALL)ALL
,其中string
可以是一切,但不能是'ALL'
”。由于sed
不支持“向前看”或“四处看”,因此最好不要在行首显式地匹配ALL
。这意味着您要查找以^[^A][^L][^L]
开头的行。虽然这在某种程度上是有限制的,但它将查找不以开头的行“ALL”
,这可能是您唯一的求助方式。比如:
sed -r '0,/^[^A][^L][^L]/s/^[^A][^L][^L][^ ]+( ALL=\(ALL\) ALL.*$)/^ABC\1/'
再次以sudoers
文件为例,包括您不想匹配的ALL=(ALL)ALL
,例如
$ cat sudoers
ALL ALL=(ALL) ALL
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
现在在ALL=(ALL)ALL
中应用表达式定位第一个
而不是ALL
,您将得到:
$ sed -r '0,/^[^A][^L][^L]/s/^[^A][^L][^L][^ ]+( ALL=\(ALL\) ALL.*$)/^ABC\1/' sudoers
ALL ALL=(ALL) ALL
^ABC ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
替换行中编号的出现项 如果要替换行中的引用。对于扩展正则表达式,使用
s/find/replace/n
,其中n=1,2,3..
是要替换的find
模式的引用,您可以将第一个引用替换为,例如
sed -r 's/[0-9a-z]+/cde456/1'
例如:
$ echo "abc123---abc123---abc123" | sed -r 's/[0-9a-z]+/cde456/1'
cde456---abc123---abc123
或者,要替换第二个引用,可以使用:
$ echo "abc123---abc123---abc123" | sed -r 's/[0-9a-z]+/cde456/2'
abc123---cde456---abc123
基本正则表达式也有相同的匹配项,您只是没有可用的“+”
(匹配一个或多个匹配项),是否必须更改查找模式,例如
sed 's/[0-9a-z][0-9a-z]*/cde456/1`
如果ALL
出现在ALL=(ALL)ALL
子字符串之前的部分中,则我理解您希望避免匹配模式的第一个匹配项
使用
如果您没有GNUsed
您可以尝试
sed -i '' -e '/^.*ALL.* ALL=(ALL) ALL/b' -e 's/^.* \(ALL=(ALL) ALL\)/abc \1\n&/' -e ':a;n;ba' file
注释
/^.*ALL.*ALL=(ALL)ALL/b
-查找在ALL=(ALL)ALL
之前包含ALL
的行,并停止处理该行
s/^.*\(ALL=(ALL)ALL\)/abc\1\n&/
执行替换(注意*
将尽可能多地匹配任何0个或更多字符)
T
-如果不成功,则结束对该行的处理
:a;Nba
-一个循环,使sed只需读取并打印文件末尾的其余行
不,我想让正则表达式匹配ALL=(ALL)ALL
where string可以是一切,但不是'ALL'。我想让正则表达式匹配ALL=(ALL)ALL,where string可以是一切,但不是'ALL'。如果您仍在忙,请澄清:是否要跳过(避免匹配)abcALL ALL=(ALL)全部
或abc全部=(全部)全部…全部…
?或者两者都有?
sed 's/[0-9a-z][0-9a-z]*/cde456/1`
sed -i '/^.*ALL.* ALL=(ALL) ALL/b;s/^.* \(ALL=(ALL) ALL\)/abc \1\n&/;T;:a;n;ba' file
sed -i '' -e '/^.*ALL.* ALL=(ALL) ALL/b' -e 's/^.* \(ALL=(ALL) ALL\)/abc \1\n&/' -e ':a;n;ba' file