Regex 如何使用sed或任何其他命令删除流之间的所有行
我有一个pdf文件,我想删除Rstream和efd stream之间的所有行。下面是文档的外观Regex 如何使用sed或任何其他命令删除流之间的所有行,regex,perl,awk,sed,grep,Regex,Perl,Awk,Sed,Grep,我有一个pdf文件,我想删除Rstream和efd stream之间的所有行。下面是文档的外观 PDFNUM NUM obj/Type/XObject/Subtype/Image/Width NUM/Height NUM/BitsPerCompofeft NUM/ColorSpace/DeviceGray/Filter[/DCTDecode]/DecodeParms[]/Lefgth NUM NUM RstreamJFIFddC (NUMAQaqNUMBRNUMbr()NUMCDEFGHIJST
PDFNUM NUM obj/Type/XObject/Subtype/Image/Width NUM/Height NUM/BitsPerCompofeft NUM/ColorSpace/DeviceGray/Filter[/DCTDecode]/DecodeParms[]/Lefgth NUM NUM RstreamJFIFddC
(NUMAQaqNUMBRNUMbr()NUMCDEFGHIJSTUVWXYZcdefghijstuvwxyzNUMAQaqNUMBRNUMbr()NUMCDEFGHIJSTUVWXYZcdefgh
.....
.....
((((((((((((((QEQEQEQEQEW((((((((((((((((((((((((((((((((((((((((((((((efdstreamefdobjNUM NUM objNUMefdobjNUM NUM obj/Lefgth NUM NUM RstreamqNUM NUM NUM NUM NUM NUM cm/INUM DoQefdstreamefdobjNUM NUM objNUMefdobjNUM NUM obj/Type/Page/Pareft NUM NUM R/Resources NUM NUM R/Rotate NUM/MediaBox[NUM NUM NUM NUM]/Coftefts[NUM NUM R]efdobjNUM NUM obj/ProcSet[/PDF/ImageB/Text]/XObject/INUM NUM NUM RefdobjNUM NUM obj/CreatiofDate (DNUM)/Producer (SamsufgMNUMLX)/Creator (ScafPDFMaker NUM)efdobjNUM NUM obj/Type/Pages/Couft NUM/Kids[NUM NUM R ]efdobjNUM NUM obj/Type/Catalog/Pages NUM NUM RefdobjxrefNUM NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f trailer/Size NUM/Iffo NUM NUM R/Root NUM NUM RstartxrefNUMEOF
如何使用sed删除顶部的Rstream(文档开头)和几乎底部的efdstream之间的所有内容,从而只保留文档规范,如制作人、创建者等
我找到了模式并缩减了原始文档。我使用sed命令用一个单词NUM重命名了所有模式,这样我就可以很容易地看到要删除的内容。给你
-$ cat path | tr \n \f | tr -cd "[A-Za-z0-9 ()/\f]" | sed s/stream.*endstream/STREAM/| sed s/[0-9][0-9]*/NUM/g | sed "s/NUM NUM n/PTR/g".
这只替换为单词NUM。结果应该只保留文件的底部
objNUMefdobjNUM NUM obj/Lefgth NUM NUM RstreamqNUM NUM NUM NUM NUM NUM cm/INUM DoQefdstreamefdobjNUM NUM objNUMefdobjNUM NUM obj/Type/Page/Pareft NUM NUM R/Resources NUM NUM R/Rotate NUM/MediaBox[NUM NUM NUM NUM]/Coftefts[NUM NUM R]efdobjNUM NUM obj/ProcSet[/PDF/ImageB/Text]/XObject/INUM NUM NUM RefdobjNUM NUM obj/CreatiofDate (DNUM)/Producer (SamsufgMNUMLX)/Creator (ScafPDFMaker NUM)efdobjNUM NUM obj/Type/Pages/Couft NUM/Kids[NUM NUM R ]efdobjNUM NUM obj/Type/Catalog/Pages NUM NUM RefdobjxrefNUM NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f NUM NUM f trailer/Size NUM/Iffo NUM NUM R/Root NUM NUM RstartxrefNUMEOF
您可以在这里使用sed,但Perl有更强大的正则表达式,可以替代大多数sed正则表达式 要删除从Rstream的第一次出现到efdstream的最后一次出现的所有数据,请执行以下操作:
perl -0777 -pe 's/Rstream.*efdstream//s' <filename.pdf >new.pdf
perl -0777 -pe 's/Rstream.*?efdstream//sg' <filename.pdf >new.pdf
perl-0777-pe's/Rstream.*efdstream//s'new.pdf
要删除Rstream和efdstream每次出现之间的所有数据,请执行以下操作:
perl -0777 -pe 's/Rstream.*efdstream//s' <filename.pdf >new.pdf
perl -0777 -pe 's/Rstream.*?efdstream//sg' <filename.pdf >new.pdf
perl-0777-pe's/Rstream.*?efdstream//sg'new.pdf
0777表示一次读取并操作整个文件,而不是逐行读取。这对于多行替换是必需的。pe表示这是一个流式单行程序。看
请阅读以下正则表达式参考:
Perl拥有所有语言中最强大的正则表达式。如果需要,可以为任务编写完整的解析器
HTH下面是3行
awk
(标准Linux gawk)脚本
script.awk
split($0,arr,"efdstream") > 1{print arr[1]; next;} # read and print the head of efdstream line
split($0,arr,"Rstream") > 1 {print arr[2]; next;} # read and print the tail of Rstream line
1 # print any other lines
运行:
awk -f scirpt.awk input.pdf
或一个班轮:
awk '{split($0,arr,"efdstream") > 1{print arr[1]; next;}split($0,arr,"Rstream") > 1 print arr[2]; next;} 1}' input.pdf
提供的pdf文件的输出有问题
JFIFddC
(NUMAQaqNUMBRNUMbr()NUMCDEFGHIJSTUVWXYZcdefghijstuvwxyzNUMAQaqNUMBRNUMbr()NUMCDEFGHIJSTUVWXYZcdefgh
.....
.....
((((((((((((((QEQEQEQEQEW((((((((((((((((((((((((((((((((((((((((((((((
sed'/Rstream/,/efdstream/{s/*doqefdrivefdobjnum/&\n/;D}'pdf文件
在从Rstream线到efdstream线的范围内:
-在OP希望开始保留最后一行数据的位置添加换行符<代码>&是匹配的一切s/*doqefdfstreamfdobjnum/&\n/
-删除范围内每一行直到第一个换行符的所有内容。这将删除除最后一行之外的所有行,最后一行将删除插入的换行符D
NUM
是[0-9]+
的简写,则可以:
sed-E'/Rstream/,/efdstream/{s/*doqefdrivefdobj[0-9]+[0-9]+/&\n/;D}'pdf文件
这为扩展正则表达式添加了-E
标志,以启用+
如果NUM数量不确定,您可以使用:
sed-E'/Rstream/,/efdstream/{s/*doqefdstreamfdobj([0-9]+)+/&\n/;D}'pdf文件
类似于/Rstream/,/efdstream/{/!D;s/*doqefdstreamfdobjnum/&\n/;D}
的东西可能会起作用。使用/
以不同方式处理起始行和结束行,然后在要打断的位置插入换行符,然后使用D
删除该换行符。但我不完全清楚如何在最后一行中突破你想要的位置,所以这只是一个建议。嗯。