在文本文件中查找双字符串的所有匹配项并进行交换

时间:2017-04-16 02:54:52

标签: regex string shell

在文本文件中搜索下划线前面带有标点符号--- [.?!;:]_ ---我希望撤消其订单。

例如,给定行

On this _line,_ I show an example. !_

我希望将其更改为:

On this _line_, I show an example. _!

我可以找到所有案例,比如Silver Searcher或ripgrep:

rg '[.?!;:]_' myfile.txt

但我不确定如何将这两个字符交换并就地写入或写入新文件。

我可以为每个标点符号实例使用sed,例如:

sed -ie 's/,_/_,/g' myfile.txt

然后

sed -ie 's/\._/_\./g' myfile.txt

...然后

但用一个命令执行此操作会很好。

我可以参考找到的实例并在ripgrep的-r ARG选项中使用它吗? 或者我咆哮错误的树并明智地使用另一个工具?

2 个答案:

答案 0 :(得分:2)

sed支持在替换参数中s调用的regex参数中定义的捕获组的反向引用(使用bash here-string语法({{ 1}})为了简洁起见:

<<<

$ sed -E 's/([.?!;:])_/_\1/g' <<<'On this _line,_ I show an example. !_' On this _line,_ I show an example. _! 是指正则表达式中的第一个捕获组(\1)。

请注意,(...)用于启用对使用现代语法的扩展正则表达式的支持 - GNU -E和BSD / macOS sed都支持此选项

通常,您不需要sed的{​​{1}}选项,除非您在多个部分中传递sed脚本,在这种情况下每个部分必须是-e - 前缀。

对于 就地更新输入文件:

sed可能做(完全)你想要的东西:当它确实更新输入文件时(通过用更新内容替换新文件),它会创建一个< em>带有后缀-e 的备份文件,因为-ie被解释为选项e选项参数

如果意图来创建备份文件,则语法 - 遗憾的是 - 根据您正在使用的e实现而有所不同:

  • GNU -ised

    • sed必须后面跟着任何其他选项/字符。
  • BSD / macOS sed -i ...-i

    • sed 必须后跟sed -i '' ...作为下一个单独的参数。

答案 1 :(得分:1)

这是一种只用一行就能做到的方法:

sed  's/\([^\w\s]\)\(_\)/\2\1/g' test.txt

基本上,你正在寻找两个角色,然后交换它们。

s / - 这开始替换

\( \) - 这会绕过括号。要做到这一点,即使它很难看。

\s一个空格字符

[ ]设置一个字符类

^否定字符类中的第一个位置

[^\w\s]所有不是字母或空格的字符(又名标点符号)

然后我们进入下一场比赛,一个下划线。我们将此作为第二项检查

\(_\) - 首先,找到标点符号并将其标记为匹配编号1,然后在其旁边找到一个下划线,并将其标记为匹配编号2.

/\2\1/ - 现在,交换匹配1和2

/g - 全球范围内这样做。

结束。现在,您可以将其输出到另一个文件,或使用其他sed修饰符(-i开关)来内联更改文件。