【问题标题】:Find all matches of two-character string in a text file and swap them在文本文件中查找两个字符串的所有匹配项并交换它们
【发布时间】:2017-09-11 23:53:28
【问题描述】:

在文本文件中搜索以标点符号开头的下划线 --- [.?!;:]_ --- 我希望颠倒它们的顺序。

例如,给定行

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 选项中使用它吗? 或者我是在找错树并明智地使用另一个工具?

【问题讨论】:

    标签: regex string shell


    【解决方案1】:

    sed 支持反向引用以捕获在替换参数中s 调用的正则表达式参数中定义的组(为简洁起见,使用bash here-string 语法 (<<<)):

    $ sed -E 's/([.?!;:])_/_\1/g' <<<'On this _line,_ I show an example. !_'
    On this _line,_ I show an example. _!
    

    \1 指正则表达式中的第一个捕获组 ((...))。

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


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

    至于就地更新输入文件:

    -ie 可能 not 做(完全)你想要的:虽然它确实更新了输入文件(通过用更新内容替换它的新文件),它创建一个 后缀为e的备份文件,因为e被解释为选项-ioption-argument

    如果不是创建备份文件的意图,那么语法 - 遗憾的是 - 根据您使用的 sed 实现而有所不同:

    • GNU sed: sed -i ...

      • -i 后面必须不能直接跟在任何其他选项/字符之后。
    • BSD/macOS sed: sed -i '' ...

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

    【讨论】:

    • 谢谢,这很好用。我无法使用 -i 就地选项,所以只使用了 sed ....... oldfile.txt > newfile.txt
    • @ChrisHanning:很高兴听到这个消息;请查看我的更新回复-i
    【解决方案2】:

    这是您可以用一行代码完成的一种方法:

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

    本质上,您正在寻找两个字符,并交换它们。

    s/ - 这会开始替换

    \( \) - 转义括号。必须这样做,即使它很丑。

    \s 一个空格字符

    [ ]设置字符类

    ^ 在字符类中的第一个位置取反

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

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

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

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

    /g - 全局执行此操作。

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

    【讨论】:

    • 这也很好用,但有一点需要注意:我无法提取 - 字符,因为它们是一种特殊情况,所以不幸的是 ^\w 作为一个包罗万象的方法不起作用我的特殊情况。对于一般情况,这也值得注意。
    • 由于_ 是不可变的,这会更简单:sed 's/\([^\w\s]\)_/_\1/g' test.txt
    猜你喜欢
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2023-01-06
    • 2013-04-16
    相关资源
    最近更新 更多