修改文本文件

时间:2011-04-22 04:28:12

标签: python regex perl

我需要以下列方式修改目录中具有“.txt”扩展名的所有文件:

删除以“xxx”开头的行开头的所有文本行以及以“xxx”结尾的行。

我知道如何在Java或C ++中执行此操作,但有人可以向我展示一个可以完成此操作的简单脚本吗?

谢谢!

3 个答案:

答案 0 :(得分:8)

我认为你想要失去开始和结束,这些单词会自己出现在你想要丢失的行上。

perl -ni.bak -e 'print unless /^start$/../^end$/' *.txt

请注意,我对修改后的文件进行了备份,以便您可以检查更改并根据需要进行修复。

答案 1 :(得分:2)

并不是说@ btilly的回答有任何问题 - 事实上,我会以自己的方式做到 - 但只是为了告诉你有多种方法可以做到,你也可以使用替代:

% perl -i.save -0777 -pe 's/^start.*end$//gsm' *.txt

这会在最后留下一个额外的换行序列,但是如果结尾处于EOF并且没有新行,则它会起作用。你也可以这样考虑:

% perl -i.save -0777 -pe 's/^start.*end$\R?//gsm' *.txt

你说的是一行以“xxx”开头,但是你没有说这就是线上的所有内容,你说的是以“xxx”结尾的那一行,但你没有说那就是那个它也在线上。你没有提到如果那些是同一条线会发生什么。我相信你会发现我的解决方案会处理这些案例。

但是,它不处理开始和结束字符串重叠的情况。如果你真的想要那个,请告诉我,我会操纵它,这样才有效。

使用Perl的另一个好处是它非常容易使用UTF-8数据文件:

bash-3.2$ cat /tmp/data
     1  fee 
     2  commencé
     3  fie foo
     4  fum
     5  terminé
     6  beat on 
     7  the drum

bash-3.2$ perl -Mutf8 -CSD -nle 'print unless /commencé/ .. /terminé/' /tmp/data
     1  fee 
     6  beat on 
     7  the drum

bash-3.2$ perl -i.guardé -Mutf8 -CSD -nle 'print unless /commencé/ .. /terminé/' /tmp/data

bash-3.2$ cat /tmp/data
     1  fee 
     6  beat on 
     7  the drum

bash-3.2$ cat /tmp/data.guardé 
     1  fee 
     2  commencé
     3  fie foo
     4  fum
     5  terminé
     6  beat on 
     7  the drum

Etvoilà! :)

这是其中一个问题领域,其中Perl特别适合极其简短,易读且可维护的答案。它确实是最终的Unix Power Tool。

显然,你永远不会从Java或C ++接近这种电动工具操作。我怀疑Ruby可能能够做类似的事情,但我认为Python离Unix风格太远,无法提供简洁明了的答案。

另外它的运行速度也非常快:不像C那样完全,但肯定比一些非常慢的shell脚本快得多。好吧,至少如果你进行行处理,那就是。将所有内容都读入内存永远不会扩展,但它可以用于小事情。此外,shell工具倾向于轰炸其中包含二进制数据或非常长的行的文件,因此您不能总是依赖它们来做这些事情,尤其是以便携式,跨平台的方式。而且几乎所有这些都不能与Unicode一起可靠地工作,这是现在必须的。

答案 2 :(得分:0)

ruby -i.bak -ne 'print unless /^start/.../^end/' *.txt