【问题标题】:Sed on Mac not recognizing regular expressionsMac 上的 Sed 无法识别正则表达式
【发布时间】:2015-08-19 17:21:53
【问题描述】:

在终端中,我正在尝试清理一些 .txt 文件,以便将它们导入另一个程序。只有文字搜索/替换似乎有效。我无法让正则表达式搜索工作。

如果我尝试搜索并用文字字符串替换,它会起作用:

find . -type f -name '*.txt' -exec sed -i '' s/Title Page// {} +;

(从每个文本文件中删除“标题页”字样)

但如果我尝试最基础的正则表达式,它就行不通:

find . -type f -name '*.txt' -exec sed -i '' s/\n\nDOWN/\\n<DOWN\>/ {} +;

(在每个文本文件中,重新格式化双回车后的任何单词“DOWN”:删除多余的换行符并将单词放在括号中:“\n”)

这不起作用。唯一的“正则表达式”就是寻找换行符。

我一定是做错了什么。

非常感谢任何帮助。

更新:第 2 部分

John1024 的回答在一方面帮助了我很多。

find . -type f -name '*.txt' -exec sed -i '' '/^$/{N; s/\n[0-9]+/\n/;}' {} +;

现在我无法让其他类型的正则表达式正确响应。上面的例子,我希望删除所有出现在行首的数字。

啊!我错过了什么?

【问题讨论】:

  • sed中替换多行并不是那么直接:How can I use sed to replace a multi-line string?
  • 如果你将整个文件放在模式空间中,它可以工作,比如':loop; N;美元!循环; ...'
  • 您显示的第一个命令应该不起作用。您显示 -exec sed -i '' s/Title Page// {} +,但由于 Title 和 Page 之间的空格,有一个不完整的替换命令后跟一个文件名 Page//。您需要使用引号(单引号或双引号)才能使其工作:-exec sed -i '' 's/Title Page//' {} +。 (问题中的分号是多余的,但在其他方面无害。)
  • 您的更新可能最好作为一个新问题提出。更准确地显示您计划编辑的输入数据(向下编辑和数字编辑)。如果您继续使用sed,您可能需要修改您的“其他命令”以识别行首的数字在模式空间中以某种方式出现(在其他行之后)。示例输入和期望的输出在这里是明智的。

标签: regex macos sed terminal grep


【解决方案1】:

默认情况下,sed 一次只处理一行。当一行被读入 sed 的模式空间时,换行符被删除。

我看到你想查找一个空行,后跟DOWN,找到后,删除空行并将文本更改为<DOWN>。这是可以做到的。将此视为测试文件:

$ cat file
some
thing
DOWN

DOWN
other

试试:

$ sed '/^$/{N; s/\nDOWN/<DOWN>/;}' file
some
thing
DOWN
<DOWN>
other

工作原理

  • /^$/

    这会寻找空行。后面的大括号中的命令只在空行上执行。

  • {N; s/\nDOWN/&lt;DOWN&gt;/;}

    N 命令将下一行读入模式空间,与当前行之间用换行符分隔。

    如果模式空间匹配空行后跟DOWN,则替换命令s/\nDOWN/&lt;DOWN&gt;/ 删除换行符并将DOWN 替换为&lt;DOWN&gt;

特殊情况:DOS/Windows 文件

如果文件有 DOS/Windows 行结尾 \r\n,sed 只会在读入该行时删除 \n\r 将保留。在处理这些文件时,如果没有预料到该字符的存在,可能会导致令人惊讶的结果。

【讨论】:

    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多