【问题标题】:How to extract multiple mailing addresses from PDF file using pdftotext如何使用 pdftotext 从 PDF 文件中提取多个邮寄地址
【发布时间】:2016-09-07 07:37:35
【问题描述】:

我在 bash 脚本中使用 pdftotext,试图从 PDF 邮资标签中提取姓名和地址。

一个示例 PDF 文件:

Delivered By:

1st Class
Postage on Account GB

First Last
HouseName
Street
Town
County
Postcode

Customer Reference: 12400 / 203 1

32224983765

RETURN TO: MyName,
DoorNumber, Street, Town,
City, Postcode, Country

121-0434 905 20200-000 6190 C228

Delivered By:

1st Class
Postage on Account GB

First Last
HouseNumber
Street
Town
Postcode

Customer Reference: 12401 / 200 1

32224286536

RETURN TO: MyName,
DoorNumber, Street, Town,
City, Postcode, Country

121-0434 905 20200-000 6190 C414

请注意:

  • 地址没有固定长度,即。有些只有 4 行,我见过一些最多 6 行。
  • PDF 文件中的地址数量不会提前知道。

到目前为止,我刚刚得到:

pdftotext label.pdf - | grep -A10 "Postage on Account GB" | tail -n+3 | head -n -3

- 避免创建文件。 grep -A10 输出匹配 "Postage on Account GB" 的前 10 行。 tail -n+3 删除匹配项和下一行。 head -n -3 删除最后 3 行。当文件中只有一个地址由 6 行组成时,这很好用,但当涉及到多个地址和不同长度时,我就卡住了。

简单地说,我想从Postage on Account GB 之后的空行之后提取数据,直到下一个空行之前的行。然后格式化输出,使地址以逗号分隔,并且每个都在一个新行上,例如:

First Last, HouseName, Street, Town, County, Postcode
First Last, HouseNumber, Street, Town, Postcode

【问题讨论】:

  • 邮寄地址的问题是它们没有遵循固定的模式。

标签: regex bash pdf grep pipe


【解决方案1】:

更新答案

鉴于您的 cmets,我已将我的答案更新如下:

pdftotext file.pdf - | perl -00 -wnl -e 'BEGIN{$a=$r=0} if($a){($add=$_)=~tr/\n/,/; $r=1; $a=0; next} if($r){printf "%s,%s\n",$_,$add;$r=0} $a=1 if m/Postage on Account/;'

每次循环读取一条记录 - 因为-00,一条记录由上下空行分隔。一开始,我将$a$r 标志设置为零,这意味着我们不查看地址或引用。如果我们正在查看地址,我会将所有换行符转换为逗号,并注意我们现在正在寻找参考。如果我们找到一个参考,我们打印它和保存的地址,并注意我们不再查看地址或参考。如果我们找到字符串“Postage on Account”,我们注意到我们现在期待一个地址。

样本输出

Customer Reference: 12400 / 203 1,First Last,HouseName,Street,Town,County,Postcode
Customer Reference: 12401 / 200 1,First Last,HouseNumber,Street,Town,Postcode

原答案

我想我会在段落模式下使用 Perl:

pdftotext file - | perl -00 -wnl -e 'BEGIN{$p=1} if($p==1){tr/\n/,/;print;$p=0}; $p=1 if /Postage/'

-00 将 Perl 设置为 段落模式 将每个空白行分隔的块视为一个段落。 BEGIN{...} 设置打印标志 ($p) 以便打印第一行。在随后的段落中,当设置打印标志时,换行符变为带有tr 的空格,并且该段落被打印并重置标志。最后,每当我们看到单词Postage 时,我们都会设置打印标志。

【讨论】:

  • 我现在又有了一个可以工作的树莓派 - 抱歉耽搁了。 @mark-setchell 您的解决方案非常接近,尽管它在首次启动时输出“Delivered By:”和一个空白行,并且在每个地址之后它还会打印一个空白行。如何删除这两个功能?我还有一个新要求,将客户参考号放在每行的开头,所以在第一个示例中,它将以 12400 / 203 1, First Last, HouseName, Street, Town, County, Postcode 开头 - 这可能吗?
  • 请再看看 - 我已经更新了我的答案。
【解决方案2】:
 pdftotext filename.pdf - |sed -n '/Postage on Account GB/,/Customer Reference:/{/Postage on Account GB/!{/Customer Reference:/!p}}' |grep . |tr '\n' ',' |sed 's/,$//g' |sed "s/Postcode/&\n/g" |sed 's/^,//g'
First Last,HouseName,Street,Town,County,Postcode
First Last,HouseNumber,Street,Town,Postcode

【讨论】:

  • 对迟到的回复表示歉意 - 在我可以尝试您的建议 (“Error: The file system is bigger than its volume!”) 之前,我仍然有一个系统启动失败需要解决,但是我不确定您的代码是否可以工作,因为您在哪里我在sed "s/Postcode/&\n/g" 中使用了“邮政编码” - “邮政编码”只是我用于示例目的的替代品,在实际情况下,该字段将显示客户的实际邮政编码,该邮政编码总是不同的。谢谢。
  • 向我们展示您要替换的内容,将尝试根据您的需要修改命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 2016-02-04
  • 2014-03-23
  • 2015-12-28
相关资源
最近更新 更多