Regex grep用于替换子字符串的意外行为
我在理解如何使用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
{ 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”命令来修复此问题,并且不需要grepsed-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