如何读取多行 fwf 格式,其中行可能流或不流多行
Posted
技术标签:
【中文标题】如何读取多行 fwf 格式,其中行可能流或不流多行【英文标题】:How to read multiline fwf format where row may or may not flow multiline 【发布时间】:2013-02-27 06:53:44 【问题描述】:我从我的一位经纪人那里得到如下文本文件的交易报告。我正在尝试解析它以进行一些分析。问题是每条记录都有多行,包括一个聚合行(标有 * 表示 BUY 或 SELL 及其下方)。
TRADE SETTL AT BUY SELL CONTRACT DESCRIPTION EX TRADE PRICE CC DEBIT(DR)/CREDIT
------- ------- -- -------------- -------------- ------------------------------ -- ----------- -- --------------------
11/26/2 F1 1 JAN 13 SOYBEAN MEAL 01 424.70 US
ELECTRONIC TRADE
F1 1* COMMISSION US 1.20DR
F1 EXCHANGE & CLEARING FEE US .81DR
F1 NFA FEE US .02DR
F1 TOTAL COMMISSION & FEES US 2.03DR
11/28/2 F1 1 DEC 12 SWISS FRANC 16 107.490 US
ELECTRONIC TRADE
F1 1* COMMISSION US 1.20DR
F1 EXCHANGE & CLEARING FEE US .54DR
F1 NFA FEE US .02DR
F1 TOTAL COMMISSION & FEES US 1.76DR
11/29/2 F1 2 MAR 13 NEW COCOA 06 24.61 US
ELECTRONIC TRADE
F1 2* COMMISSION US 2.40DR
F1 EXCHANGE & CLEARING FEE US 4.00DR
F1 NFA FEE US .04DR
F1 TOTAL COMMISSION & FEES US 6.44DR
12/03/2 F1 1 DEC 12 IMM EURO FX 16 1.30000 US
ELECTRONIC TRADE
F1 1* COMMISSION US 1.20DR
F1 EXCHANGE & CLEARING FEE US .54DR
F1 NFA FEE US .02DR
F1 TOTAL COMMISSION & FEES US 1.76DR
12/07/2 F1 3 DEC 12 US $ INDEX 13 80.245 US
ELECTRONIC TRADE
12/07/2 F1 3 DEC 12 US $ INDEX 13 80.250 US
ELECTRONIC TRADE
F1 3* 3* COMMISSION US 7.20DR
F1 EXCHANGE & CLEARING FEE US 8.10DR
F1 NFA FEE US .12DR
F1 TOTAL COMMISSION & FEES US 15.42DR
目前我只对聚合信息感兴趣,即 CONTRACT DESCRIPTION
、BUY
和 SELL
中带有 * 的数量以及下面的字段,即 COMMISSION
、EXCHANGE AND CLEARING FEES
、NFA FEE
和 TOTAL COMMISSION AND FEES
值如最后一列 DEBIT(DR)/CREDIT
中指定的那样?
任何指示我该怎么做?
我尝试使用read.fwf
,但它对我不起作用,因为每条记录的多行格式不同。
最终,如果没有任何效果,我将不得不逐行编写解析器,目前我正试图避免这样做,看看是否可以以更优雅的方式完成。
【问题讨论】:
从上面的示例中,您能否更新您的问题,以您想象的格式显示您感兴趣的数据? 【参考方案1】:由于您的数据按日期分组,因此我对其进行扫描并使用lapply
对其进行处理。
dat <- scan('yourfile_name',what='character')
ids <- c(grep('[0-9]+/[0-9]+/[0-9]',dat),length(dat))
lapply(head(seq_along(ids),-1),function(x)
y <- dat[ids[x]:(ids[x+1]-1)]
list( desc = paste(y[4:8] ,collapse=' '),
dd = y[1],
debit_credit = y[grep('.*DR',y)],
trde_price = as.numeric(y[grep('[0-9]+[.][0-9]+$',y)])
)
)
[[1]]
[[1]]$desc
[1] "JAN 13 SOYBEAN MEAL 01"
[[1]]$dd
[1] "11/26/2"
[[1]]$debit_credit
[1] "1.20DR" ".81DR" ".02DR" "2.03DR"
[[1]]$trde_price
[1] 424.7
[[2]]
[[2]]$desc
[1] "DEC 12 SWISS FRANC 16"
.....
PS:我丢失了B/S的信息。希望这会有所帮助。
【讨论】:
谢谢!这对我来说已经足够好的开始了。用日期拆分它对我来说是一个很好的起点。 @geektrader 酷!告诉我你是否有 B/S 信息的解决方法。【参考方案2】:agstudy 的回答看起来很有帮助。我将建议一种替代方法:首先修复 bleeping 输入文件。如果您无法访问源程序并更改输出格式,至少您可以在任何文本编辑器中执行以下操作(甚至,我敢说,MicrosoftWord :-))。
编辑:以下建议是倒退的,即您可能希望仅保留后跟日期字符串的行尾。概念是相同的,但修改搜索词以查找 "anything but..." 。抱歉误导了。
对段落标记(行尾)进行全局搜索并替换后跟两位数字和“/”,并替换为制表符和相同的两位数字和“/”
在 Word 中,这将是 FIND what ^13([0-9]2,2/) REPLACE with ^t\1
;支持正则表达式的编辑器会有所不同。
现在,您的源文件中的每个日期条目都有一个(较长的)行,您可以轻松提取感兴趣的列。
【讨论】:
感谢您的建议。我想修复文件,但我仍然需要以编程方式完成,我希望在 R 中完成所有操作。 @geektrader 你可以在R
中做“任何事情”,即使这意味着system('awk your_file something_regexp-y')
:-)以上是关于如何读取多行 fwf 格式,其中行可能流或不流多行的主要内容,如果未能解决你的问题,请参考以下文章