我需要从文件中提取文本字符串并将它们放入新文件中。每个字符串始终位于相同的文本(标签)之间。
这是一个示例(有数百个像这样的块,我需要将其中的数据放入一个文件中):
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj
我需要提取第 250 页和要提取的文本示例
为了第 250 页例如,相关标签似乎是:
<</
和
/Type
为了要提取的文本示例例如,相关标签似乎是:
/Contents(
和
)/F
最终,我希望页面和相应的文本按升序排序,但我可以在电子表格中进行管理。
我尝试使用一些答案这里,但我没能让它发挥作用......
我最熟悉 Unix 命令行,但我了解一点 Python 和 AppleScript
答案1
和awk
:
awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) \
if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
将字段分隔符设置为
/
,如果第一个字段是<<
,则将第二个字段保存为变量以便i
稍后打印迭代其余字段,如果有任何字段以 开头
Contents
,则将该字段拆分()
以创建数组a
,for(j=3;j<=NF;j++) if($j~/^Contents/) split($j,a,"[()]")
打印变量
i
和数组的第二个元素,a
将它们分开_
例子:
% cat file.txt
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj
% awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
Page 250 _ EXAMPLE OF TEXT TO BE EXTRACTED
答案2
我将您的示例内容添加到磁盘文件命名的文件然后显示内容文件使用cat
命令。然后使用awk
onfile
我基本上删除了你正在调用的部分标签并打印出两块数据在一个制表符分隔格式。这是您要找的吗?
$ cat file
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj
$ awk '{sub(/\<\<\//, "")};{sub(/\/Type.*\/Contents\(/, "\t")};{sub(/\)\/F.*$/, "")};/Page [0-9]/{print}' file
Page 250 EXAMPLE OF TEXT TO BE EXTRACTED
$
什么是awk
程序是在做:
/Page [0-9]/
正在搜索包含空格(即“Page”)后跟数字(例如 )的行Page 250
。我假设EXAMPLE OF TEXT TO BE EXTRACTED
不会包含该模式。我认为这并不重要,尽管代码可以很容易地修改以适应这一点。sub(/\<\<\//, "")
带子:<</
sub(/\/Type.*\/Contents\(/, "\t")
正在用选项卡替换/Type
和之间的所有内容。/Contents(
sub(/\)\/F.*$/, "")
正在剥离从)/F
该行到末尾的所有内容。
所以剩下的就是打印出来的内容。两件通缉品数据用制表符分隔。
我知道这并没有涵盖您提到的所有方面,但是您的其他要求还不够明确。您需要处理的只是一个文件还是多个文件。在任何一种情况下,您是否希望将所有提取的数据放入一个文件中,以及数据的排序方式等等。
所以如果你能澄清一些事情我可能会写一个bash脚本覆盖它。
显然与awk
程序我已经提供了,您可以将输出重定向到输出文件并继续处理它sort
命令。 也可以进行排序,但是此时awk
我可以在一个命令行中获取目标数据。awk