我正在尝试解析 PDF 报告中的数据并过滤掉某些有趣的元素。使用pdftotext -layout
我获取这种格式的数据作为我的起点:
Record Info Interesting
123 apple yep
orange nope
lemon yep
-----------------------------------------------
456 dragonfruit yep
cucumber nope
-----------------------------------------------
789 kumquat nope
lychee yep
passionfruit yep
yam nope
-----------------------------------------------
987 grapefruit nope
我的预期输出是这样的 - 每个“ Interesting
”水果及其记录编号除了当该水果是其记录中的第一个水果时:
Record Info
123 lemon
789 lychee
789 passionfruit
目前,受到启发这个问题,我将------
记录分隔符替换为 ,\n\n
并使用 删除记录标题sed
。然后我可以找到具有匹配记录的段落awk
:
awk -v RS='' '/\n .....................yep/'
(弄清楚如何用{3}.{21}
其中一个awk
s 来书写或类似绝对是另一天的战斗:/)
这会产生如下所示的清理段落:
123 apple yep
orange nope
lemon yep
789 kumquat nope
lychee yep
passionfruit yep
yam nope
从这里我可以通过以下方式获得所需的输出:
- 添加第二个记录编号列,该列由第一个记录编号列或上一行的第二个记录编号列填充
- 删除第一列中有记录号的行
- 删除不感兴趣的行
cut
出最后一列
我在这里是否大体朝着正确的方向前进,或者是否有更直接的方法来解析多维数据?也许通过grep
ping 一个有趣的行(有yep
或没有记录号),然后grep
从那里向后到具有非空记录号的下一行?
答案1
你可能把事情过于复杂化了:
$ cat input
Record Info Interesting
123 apple yep
orange nope
lemon yep
-----------------------------------------------
456 dragonfruit yep
cucumber nope
-----------------------------------------------
789 kumquat nope
lychee yep
passionfruit yep
yam nope
-----------------------------------------------
987 grapefruit nope
$ awk 'BEGIN {OFS="\t"; print "Record","Info"} NF==3 && NR!=1 { number=$1 } NF!=3 && $2 ~ /yep/ {print number,$1}' input
Record Info
123 lemon
789 lychee
789 passionfruit
为了使awk
脚本更加垂直,解释它是如何工作的:
BEGIN { # This block executes before any data
OFS="\t"; # are parsed, and simply prints a header.
print "Record","Info"
}
NF==3 && NR!=1 { # This block will run on any row (line)
number=$1 # with three fields other than the first
}
NF!=3 && $2 ~ /yep/ { # On rows with three fields where the second
print number,$1 # matches the regex /yup/, print the number
} # grabbed before, and the fruit.