删除最接近另一个图案的图案之间的线

时间:2018-07-18 22:58:31

标签: awk sed

我正在尝试从PDF文件中删除某些对象。所有对象看起来像这样:

40 0 obj 
<<
/PieceInfo 
/Subtype /Form
/Resources 
<<
/Font 
<<
/Fm1 35 0 R
>>
>>
/Type /XObject
/BBox [0 -22.5 131.05 0]
/Length 601
/Matrix [1 0 0 1 0 0]
>>
stream
  . . .
  A bunch of compressed gibberish here
  . . .
endstream 
endobj

我发现在不破坏PDF文档的情况下可以删除objstreamendstream之间的内容。

sedawk中是否可以找到包含/Form的行,然后删除最近的obj和下面的stream之间的所有内容,以及下面的streamendstream,这样最终结果看起来像这样:

40 0 obj 
stream
endstream 
endobj

5 个答案:

答案 0 :(得分:0)

给出:

$ echo "$pdf"
40 0 obj 
<<
/PieceInfo 
/Subtype /Form
/Resources 
<<
/Font 
<<
/Fm1 35 0 R
>>
>>
/Type /XObject
/BBox [0 -22.5 131.05 0]
/Length 601
/Matrix [1 0 0 1 0 0]
>>
stream
  . . .
  A bunch of compressed gibberish here
  . . .
endstream 
endobj

您可以使用perl

$ echo "$pdf" | perl -0777 -lne 'print "$1$2$3\n" if /(^.*(?<=\bobj)\s*\R)[\s\S]*?\/Form[\s\S]*?^(stream\s*^)[\s\S]*?^(endstream\s+endobj)/m'
40 0 obj 
stream
endstream 
endobj

Demo and explanation of regex

答案 1 :(得分:0)

perl -0777 -pe 's/(?<=obj)[\s\S]+?\/Form[\s\S]+?\n(?=endstream)/\nstream\n/g' pdf

此正则表达式可以通过多种方式适得其反(关键问题是出现在中间的“ obj”或“ endstream”或缺少这些字段或“ / Form”)。您将需要一个完整的脚本来获得某种生产质量,在这种情况下,您肯定需要“展示您的作品”以获得帮助。另外,对于实际的PDF,您可能需要在\n之前删除或更改(?=endstream)。我不熟悉它使用的行尾字符。

第一个理由是,jist会寻找obj*/Form*endstream,然后掩盖所有不在环视(?[etc])中的内容,然后手动读取stream行。

答案 2 :(得分:0)

awk也可以完成这项工作,

awk '/[^end]obj/||/[end]*stream/{print;if(d==1){s=""}d=1;next}{s=s $0}END{print s}' pdf

简要说明,

  1. /[^end]obj/||/[end]*stream/:找到字符串'obj','stream'和'endstream'
  2. 如果该行中存在上述字符串,则将其打印并启用标志d
  3. 如果已经启用d,请清除缓冲区str
  4. 最后打印str

答案 3 :(得分:0)

这可能对您有用(GNU sed):

sed -r '/\<obj\>/{n;:a;/\<endobj\>/!{N;ba};s/.*\<(stream)\>.*\<(endobj)\>/\1\n\2/}' file

聚集objendobj之间的线,并删除stream两侧的部分。

答案 4 :(得分:-1)

$ cat tst.awk
$NF == "endobj" {
    print (obj ~ "/Form" ? "stream" ORS "endstream" : obj)
    obj = ""
    inObj = 0
}
inObj  { obj = (obj == "" ? "" : obj ORS) $0 }
!inObj { print }
$NF == "obj" { inObj = 1 }

$ awk -f tst.awk file
40 0 obj
stream
endstream
endobj