Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何使用sed或任何其他命令删除流之间的所有行_Regex_Perl_Awk_Sed_Grep - Fatal编程技术网

Regex 如何使用sed或任何其他命令删除流之间的所有行

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

我有一个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()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线的范围内:

    • s/*doqefdfstreamfdobjnum/&\n/
      -在OP希望开始保留最后一行数据的位置添加换行符<代码>&是匹配的一切
    • D
      -删除范围内每一行直到第一个换行符的所有内容。这将删除除最后一行之外的所有行,最后一行将删除插入的换行符
    给定输入,将产生预期的输出。。。最后一行,在efdstream和两个相关NUM之后截断

    如果
    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
    删除该换行符。但我不完全清楚如何在最后一行中突破你想要的位置,所以这只是一个建议。嗯。