我需要以下列方式修改目录中具有“.txt”扩展名的所有文件:
删除以“xxx”开头的行开头的所有文本行以及以“xxx”结尾的行。
我知道如何在Java或C ++中执行此操作,但有人可以向我展示一个可以完成此操作的简单脚本吗?
谢谢!
答案 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