我有一堆包含半标准标题的文件。也就是说,它的外观非常相似,但文字有所改变。
我想从所有文件中删除此标头。
通过查看文件,我知道我要删除的内容被封装在相似的单词之间。
所以,例如,我有:
Foo bar...some text here...
more text
Foo bar...I want to keep everything after this point
我在perl中尝试了这个命令:
perl -pi -e "s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
但它不起作用。我不是正则表达式专家,但希望有人知道如何基于文本匹配而不是字符数从文件开头基本上删除一大块文本......
答案 0 :(得分:7)
默认情况下,ARGV
(在<>
幕后使用的-p
)一次只能读取一行。
解决方法:
取消设置$/
,告诉Perl一次读取整个文件。
perl -pi -e "BEGIN{undef$/}s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
BEGIN
是在第一次读取完成之前运行该代码所必需的。
使用-0
设置$/ = "\0"
。
perl -pi -0 -e "s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
perl -ni -e "print unless 1 ... /^Foo.bar/'
这将跳过从第1行开始到/^Foo.bar/
的打印。
答案 1 :(得分:3)
如果您的标题跨越多行,您必须告诉perl要阅读多少。如果文件与内存相比较小,您可能只想将整个文件粘贴到内存中:
perl -0777pi.orig -e 's/your regex/your replace/s' file1 file2 file3
-0777
选项将perl设置为slurp模式,因此$_
每次都会保存每个整个文件。此外,请始终记住设置备份扩展名。如果不这样做,您可能会发现您意外删除了数据并且无法将其恢复。有关详细信息,请参阅perldoc perlrun
。
根据评论中的信息,您似乎试图从Project Gutenberg电子书的前面删除所有恼人的内容。如果您了解所涉及的所有版权问题,您应该能够摆脱这样的前提问题:
perl -ni.orig -e 'print unless 1 .. /^\*END/' 00ws110.txt
Project Gutenberg标题以
结尾*END*THE SMALL PRINT! FOR PUBLIC DOMAIN ETEXTS*Ver.04.29.93*END*
更安全的正则表达式也会考虑到行尾的*END*
,但我很懒。
答案 2 :(得分:2)
我可能会误解你所要求的东西,但它看起来很简单:
perl -ni -e 'print unless 1..($. > 1 && /^Foo bar/)'
答案 3 :(得分:0)
你走了!这将替换文件的第一行:
use Tie::File;
tie my @array,"Tie::File","path_to_file" or die("can't tie the file");
$array[0] =~s/text_i_want_to_replace/replacement_text/gi;
untie @array;
您可以对阵列进行操作,您将看到阵列中的修改。您可以从数组中删除元素,它将从文件中删除该行。在元素上应用替换将替换行中的文本。
如果你想删除前两行,并保留第三行,你可以这样做:
# tie the @array before this
shift @array;
shift @array;
$array[0]=~s/foo bar\.\.\.//gi;
# untie the @array
这将完全符合您的需求!