【问题标题】:Using sed to clean up text files using regular expressions使用 sed 使用正则表达式清理文本文件
【发布时间】:2015-06-05 11:33:50
【问题描述】:

上一个问题的继续 Sed on Mac not recognizing regular expressions

我正在编辑和清理多个文本文件,准备将它们输入到另一个软件中。我无法让 Sed 处理实际的正则表达式:

我知道这些是不正确的,但我能最接近地描述我感兴趣的代码。请将两行代码与输入和输出进行比较。

非常感谢任何帮助。

  1. 去掉行首的所有数字:

    find . -type f -name '*.txt' -exec sed -i '' '/^$/{N; s/\n[0-9]+/\n/;}' {} +
    
  2. 格式化文件:

    find . -type f -name '*.txt' -exec sed -i '' '/^$/{N; s/([^\n]+)\nACROSS\n/<ACROSS PUZZLE>\n<TITLE>\n\1\n<AUTHOR>\n\n<COPYRIGHT>\n\n<SIZE>\n15x15\n<GRID>\n<ACROSS>\n/;}' {} +
    
  3. 任何时候有两个或多个下划线,只替换为三个

    find . -type f -name '*.txt' -exec sed -i '' '/^$/{N; s/\_\_+/\_\_\_/;}' {} +
    
  4. 如果点之间有省略号,请删除空格:

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

输入:

nxd-12345678 Serial number of file
Title of File
ACROSS
1 __ fast
2 IRS-form experts
10 Lend. . .
12 Deals with adversity

输出:

nxd-12345678 Serial number of file
<ACROSS PUZZLE>
<TITLE>
Title of File
<AUTHOR>

<COPYRIGHT>

<SIZE>
15x15
<GRID>
<ACROSS>
___ fast
IRS-form experts
Lend...
Deals with adversity

【问题讨论】:

  • 标题总是在第二行吗? ACROSS 会一直出现在第三行吗?其余的都是直截了当的。
  • 我很惊讶还没有人知道你 - sed 总是不适合做任何跨越多行的事情。您应该使用 awk。
  • 编辑。不,没有人这样做。我是前端开发人员,所以我只有这样的基本知识。我的知识主要限于 PHP 之类的东西。我对命令行技能没有太多用处。但我能够回答我所有的问题。我最终完成的这个脚本将几个不同的任务组合成一个脚本。在准备一堆文件时节省大量时间,在此脚本之前,这些文件需要大量手动处理数据,以便为最终目的地做好准备。

标签: regex macos sed


【解决方案1】:

假设谜题的标题出现在第二行,而第三行总是ACROSS,那么就没有什么大问题了:

sed -e '2,$s/^[0-9][0-9]* *//' \
    -e 's/\. \. \./.../g' \
    -e 's/___*/___/g' \
    -e '2i\
<ACROSS PUZZLE>\
<TITLE>' \
    -e '2a\
<AUTHOR>\
\
<COPYRIGHT>\
\
<SIZE>\
15x15\
<GRID>\
<ACROSS>' \
    -e '/^ACROSS$/d'

第一个表达式处理除第一行之外的每一行开头的数字,其中似乎保留了数字,尽管声称代码应该“删除行首的所有数字”。

第二行用点之间的空格替换省略号,点之间没有空格的省略号。

第三行是用三个下划线替换任意两个或多个下划线序列的一种方法。

第三、第四和第五行在标题行之前插入&lt;ACROSS PUZZLE&gt;&lt;TITLE&gt; 行。

第 6 行到第 14 行将其他常量材料插入到文件中。

脚本的最后一行删除了数据的ACROSS 行。

您可以创建小文件并在适当的位置读取这些文件,而不是使用插入和追加操作。

sed -e '2,$s/^[0-9][0-9]* *//' \
    -e 's/\. \. \./.../g' \
    -e 's/___*/___/g' \
    -e '1r file.1' \
    -e '2r file.2' \
    -e '/^ACROSS$/d'

其中file.1 包含:

<ACROSS PUZZLE>
<TITLE>

file.2 包含:

<AUTHOR>

<COPYRIGHT>

<SIZE>
15x15
<GRID>
<ACROSS>

这更容易理解,但会给您留下几个要删除的中间文件,即使有人变得粗鲁并按下中断键。这很容易管理,但超出了当前问题的范围。

结合您的其他问题,您可以像上面一样对待DOWN 行。实际上,您可以很容易地将ACROSS 替换为&lt;ACROSS&gt;,并将DOWN 替换为&lt;DOWN&gt;。如果有不需要的空白行,您可以删除它们。通过确保整行包含DOWNACROSS(仅此而已),您可以避免出现填字游戏的异常线索。

【讨论】:

  • 感谢您的快速回复。您注意到序列号是正确的。但是,我错误地指定了序列号。实际上,每个文档的序列号都以一些字母开头。我很抱歉在我的示例中只使用伪代码。我应该更准确。序列号均以字母“nxd”开头。所以真正的序列号格式是:"nxd-########"
  • 好的;这简化了生活。只需从第一个表达式中删除 2,$。或者,确实,把它留在那里——它没有害处,因为你的第一行不会以数字开头。问问题时要小心。回答的人只有你告诉他们使用的东西,所以他们会逐字使用。
  • 你不需要所有那些-e,只需要第一个和其余的在同一个字符串中(使用; 或换行[更适合人类阅读]作为动作分隔符)
  • sed 不需要它们来理解它。对于阅读脚本的人来说,它们是 IMNSHO 必需的,或者至少是有帮助的。
猜你喜欢
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 2012-04-10
  • 2018-04-23
相关资源
最近更新 更多