Regex grep用于替换子字符串的意外行为

Regex grep用于替换子字符串的意外行为,regex,replace,grep,substring,oh-my-zsh,Regex,Replace,Grep,Substring,Oh My Zsh,我在理解如何使用grep来完成一项看似简单的任务时遇到了一些困难。我想匹配出现在我拥有的很多文件中的子字符串,但我想忽略这个子字符串前面有字母或数字的情况 例如,我有一堆文件,行如下: { some word: ['bar-something', 'bar-somthing-else'] }, { some text: ['bar-fab', 'bar-fab-foo', 'bar-eggs'] }, <bar-sometext>Hello World!</bar-somete

我在理解如何使用grep来完成一项看似简单的任务时遇到了一些困难。我想匹配出现在我拥有的很多文件中的子字符串,但我想忽略这个子字符串前面有字母或数字的情况

例如,我有一堆文件,行如下:

{ some word: ['bar-something', 'bar-somthing-else'] },
{ some text: ['bar-fab', 'bar-fab-foo', 'bar-eggs'] },
<bar-sometext>Hello World!</bar-sometext>
'bar-foobar-foo'
'bar-foo'
应改为

'ket-foobar-foo'
但是我遇到了一些麻烦,因为grep命令与它们自己的规则不一致

让我解释一下:

命令:

git grep -l 'bar-' | xargs sed -i '' -e 's/bar-/ket-/g' 
几乎可以工作,唯一的问题是它还改变了前面有字母或数字的栏:

'bar-foobar-foo'
'ket-fooket-foo'

要做一些测试,在进行替换之前,我只与grep匹配。我期待着命令

grep -E '[^a-zA-Z0-9]ket-' a.file 
git grep -l 'bar-' | xargs sed -i '' -e 's/bar-/ket-/g'
完成了这个技巧,但它也匹配单词ket-前面的任何特殊字符。例如,是否匹配

<bar-

'bar-

\bar-
在我的Mac上使用oh my zsh终端运行得非常好,我将非常感谢任何与上述命令类似的答案


提前感谢

也许,您应该使用另一种支持查找断言的工具

perl -pi.bak -e 's/(?<![\p{L}\d])bar/test/g' file.txt
perl-pi.bak-e/(?使用GNU-sed:

sed 's/\([^[:alnum:]]\)bar/\1ket/g' file
这是一种sed替换,形式为
's/pattern/replace/g'
,其中
g
表示全局

匹配模式的意思是:一个非字母数字字符后跟“bar”。替换字符是匹配的字符(
\1
),后跟
\ket
。匹配模式中括号之间嵌套的任何字符都可以重新用于替换,如
\1
\2
等,直到
\9


您可以就地执行,就像在您的示例命令中一样(以及任何特定于macOS的调整)。此外,
grep
不用于替换,它只提取文本,通常没有理由将其与awk或sed一起使用。

您可以执行两次“sed”命令来修复此问题,并且不需要grep
sed-i-e“s/'bar-/'ket-/g”
sed-i-e“s/Hi@Karthikeyan,几乎可以工作(在这个简短的示例中,它只需要管理反斜杠的大小写),但我假设我需要添加一行新行来处理每个特殊情况,例如像
sed-i-e“s/\bar-/\ket-/g”这样的命令
。现在我需要弄清楚如何将其应用于我的所有文件,因为它们有数千个。通配符*会输出以下错误消息:
sed:in-place editing仅适用于常规文件
。但是,谢谢你,你的答案肯定是构建一个适用于我预期案例的答案的极好起点。注意,它更有效ent将两个单字符匹配模式连接到一个字符类,
(?=>
(?,以避免在开始时进行额外的回溯。Hi@thanasisp我使用grep递归地替换目录和子目录中的所有文件。因为我有数千个文件,我需要一种方法来将更改应用于所有文件。由于某些原因,您的解决方案与行以开头的情况不匹配。您可以递归执行此操作为您想要的所有文件自动执行。
find
可以执行此操作,或者使用glob file参数。例如:
find…| xargs sed-i…
我还看到它匹配以
-
开头的行,如果您有一个示例行不匹配,请使用此示例更新。对不起,昨天我用正确的示例编辑了我的注释但显然它没有更新。不匹配的情况是:
bar somthing
bar另一件事
,也就是说,如果“bar”是单词的开头,上面的解决方案会跳过这些情况。另外,我想匹配子字符串
bar
前面有空格的情况,例如,我想e替换:
someTex-moretext-barSomeWord
someTex-moretext-ketSomeWord
对不起,我现在没有时间关注这个问题的任何变化,祝你好运,祝你有一个愉快的一天!
perl -pi.bak -e 's/(?<![\p{L}\d])bar/test/g' file.txt
sed 's/\([^[:alnum:]]\)bar/\1ket/g' file