如果有人能够理解如何将内容存储在内存中,知道它在哪里,以及如何以有序的方式再次将其删除,那么在Perl中实现结果将会有很长的路要走。(可能还有所有的编程语言)
我不是程序员。
我正在尝试从旧程序中提取数据'输出并将其导入SQL数据库。提取是件事。
我之前的问题在很大程度上是不正确的,因为我在将数据导入表格时发现,因为我没有足够的数据来自旧程序'输出文件。
我想从错误中吸取教训并重新问我之前的问题,希望这次是正确的。
我在提取数据方面做得很差,就像上次一样。它无法获得正确的数据。
我认为这是一个非常复杂的问题,但也许并非如此。 它肯定高于我目前的Perl水平,也许永远都是。
对我错误措辞问题的答案已被部分理解。非常感谢他们。
如果我可以总结一下,我的主要任务就是处理问题的类型:'如果一行包含......从两行获取数据并将其插入...的开头...对我来说似乎不可能。 我在行搜索结束时尝试了正则表达式,但无法使其正常工作。 我也无法按照我的意愿安排连续循环来在行中插入数据。如果一个循环工作,下一个循环没有,依此类推。我准备一步一步地处理连续的文件,但是两行排除了'问题完全困扰了我。
我能够相对轻松地从这些输出文件中提取其他数据,因为它们是非常有序的文件,但是这个特殊的问题让我很难过。
我修改过的问题是:
我的输入文件包含以下格式的批量数据(+ - 50 - 70行):
1(P1) 3 P.ell 05/0120 W/P068819 0 12.0 98/99 380 380 C03 104 PROCESSED 21/02/16 TIME 22.16.52 KSINA=8
AGE SPH %THN %INC SV SI MAI20 HTPC VIPC AGE BA DBH HT SPH CIH% CIV% CVD BCON CMAI C0 C0CAL SI20
0 1100 .0 89.0%SPH 2 2 .00 .0 .0 20.00 1 .0 17.3 0 .0 .0 .0 .0 .0000 .000 0% .00
7 815 25.9 .0 2 2 9.90 75.5 47.2 20.00 1 26.6 17.3 330 .0 .0 .0 13.0 .2099 1.005 .000 17.30
13 550 32.5 .0
18 330 40.0 .0
45 0 100.0 .0
0SQ -4 -4 -4 = SI20 17 17 17 PLANTN---104 GREEN MEADOWS MODEL---P.ELLIOTTII MAC MAC SQ 10 SI20 22.90
HTPC 76 76 76 =MAI20 10 10 10 FROM HTPC HTPC 100 MAI20 20.71
VIPC 47 47 47 =MAI20 10 10 10 HTPC/VIPC REGRESSION---P.ELLIOTTII GENERAL 1/83 VIPC 100 MAI20 20.99
MAIDBH 0
INMAI==> 0
0INPUT FOR CALCULATING HTPC & VIPC = HT ---- ----
AGE DBH HT VTREE SPH BA TOTAL WS UTIL S A B C D TCAI CTCAI TMAI UCAI CUCAI UMAI SCAI CSCAI SMAI IAGE
1 .0 .2 .0000 979 0 0 0 0 0 0 0 0 0 .0 0 .0 .0 0 .0 .0 0 .0 1.0
2 .0 .9 .0000 979 0 0 0 0 0 0 0 0 0 .0 0 .0 .0 0 .0 .0 0 .0 2.0
3 3.9 2.0 .0007 979 1 1 1 0 0 0 0 0 0 .7 1 .2 .0 0 .0 .0 0 .0 3.0
4 7.1 3.4 .0041 979 4 4 3 1 1 0 0 0 0 3.4 4 1.0 .6 1 .2 .0 0 .0 4.0
5 9.4 4.6 .0102 979 7 10 5 5 5 0 0 0 0 5.9 10 2.0 4.1 5 .9 .0 0 .0 5.0
6 11.3 5.7 .0188 979 10 18 6 12 12 1 0 0 0 8.4 18 3.1 7.5 12 2.0 .0 0 .0 6.0
7 13.0 6.7 .0293 979 13 29 7 22 19 3 0 0 0 10.3 29 4.1 9.7 22 3.1 .0 0 .0 7.0
17%
THN 11.4 6.7 .0230 164 2 4 1 3 2 0 0 0 0
REM 13.4 6.7 .0315 815 12 26 6 20 17 3 0 0 0
8 15.0 7.6 .0453 815 14 37 6 31 21 10 0 0 0 11.2 40 5.0 10.9 33 4.1 .0 0 .0 7.6
9 16.4 8.5 .0607 815 17 49 6 43 23 20 0 0 0 12.5 52 5.8 12.2 45 5.0 .2 0 .0 8.6
10 17.4 9.4 .0771 815 19 63 7 56 24 30 2 0 0 13.4 66 6.6 13.1 58 5.8 1.3 2 .2 9.6
11 18.3 10.3 .0941 815 21 77 7 70 24 41 5 0 0 13.9 80 7.3 13.6 72 6.5 3.0 5 .4 10.6
12 19.0 11.3 .1118 815 23 91 7 84 24 50 10 0 0 14.4 94 7.8 14.1 86 7.2 5.4 10 .8 11.6
13 19.6 12.2 .1299 815 25 106 8 98 24 56 18 0 0 14.7 109 8.4 14.4 100 7.7 8.0 18 1.4 12.6
33%
THN 17.5 12.2 .1044 265 6 28 2 25 8 15 3 0 0
REM 20.6 12.2 .1421 550 18 78 5 73 16 42 15 0 0
14 21.3 13.0 .1636 550 20 90 6 84 16 44 25 0 0 11.8 121 8.6 11.6 112 8.0 10.0 28 2.0 10.4
15 22.0 13.7 .1864 550 21 103 6 97 16 45 36 0 0 12.5 133 8.9 12.3 124 8.3 11.0 39 2.6 11.2
16 22.7 14.5 .2100 550 22 116 6 109 15 46 48 0 0 13.0 146 9.1 12.7 137 8.6 12.0 51 3.2 12.0
17 23.3 15.3 .2345 550 23 129 6 123 15 46 61 0 0 13.5 160 9.4 13.2 150 8.8 12.9 64 3.8 12.8
18 23.9 15.9 .2598 550 25 143 7 136 15 46 74 1 0 13.9 174 9.6 13.6 164 9.1 13.8 78 4.3 13.6
40%
THN 21.6 15.9 .2142 220 8 47 2 45 6 19 20 0 0
REM 25.3 15.9 .2901 330 17 96 4 92 9 28 54 1 0
19 26.0 16.6 .3203 330 17 106 4 101 9 27 63 3 0 10.0 184 9.7 9.8 174 9.1 10.5 88 4.6 11.0
20 26.6 17.3 .3519 330 18 116 5 112 9 27 71 5 0 10.4 194 9.7 10.2 184 9.2 10.6 99 4.9 11.7
21 27.2 18.0 .3849 330 19 127 5 122 9 27 80 8 0 10.9 205 9.8 10.7 194 9.3 11.1 110 5.2 12.4
22 27.9 18.7 .4192 330 20 138 5 133 8 26 87 11 0 11.3 216 9.8 11.1 206 9.3 11.5 121 5.5 13.2
23 28.4 19.3 .4546 330 21 150 5 145 8 26 94 16 0 11.7 228 9.9 11.4 217 9.4 11.8 133 5.8 14.0
24 29.0 20.0 .4914 330 22 162 5 157 8 26 101 22 0 12.2 240 10.0 11.9 229 9.5 12.3 145 6.1 14.9
25 29.6 20.6 .5292 330 23 175 6 169 8 25 106 29 0 12.5 253 10.1 12.2 241 9.6 12.6 158 6.3 15.7
26 30.2 21.2 .5682 330 24 188 6 182 8 25 112 37 0 12.9 265 10.2 12.6 254 9.8 13.0 171 6.6 16.5
27 30.7 21.8 .6083 330 25 201 6 194 8 25 115 46 0 13.2 279 10.3 13.0 267 9.9 13.3 184 6.8 17.3
28 31.3 22.4 .6492 330 25 214 7 208 8 24 119 56 1 13.5 292 10.4 13.2 280 10.0 13.6 198 7.1 18.2
29 31.9 23.0 .6908 330 26 228 7 221 8 24 122 65 2 13.7 306 10.5 13.5 293 10.1 13.8 212 7.3 19.0
30 32.4 23.5 .7332 330 27 242 7 235 8 24 123 77 3 14.0 320 10.7 13.7 307 10.2 14.0 226 7.5 19.8
31 33.0 23.9 .7766 330 28 256 7 249 8 24 125 88 5 14.3 334 10.8 14.0 321 10.4 14.3 240 7.7 20.4
32 33.6 24.4 .8202 330 29 271 8 263 8 23 126 99 7 14.4 349 10.9 14.1 335 10.5 14.4 255 8.0 21.0
首先,第一行中的两个变量(1(P1 ...):在这种情况下' C03 104'需要从中提取并发送到OUTPUT。(与上一个问题相同,但输出位置会发生变化。)
其次,所有以' THN'开头的行除了可以丢弃THN之外,需要提取它们。 如果有两个,三个,四个甚至五个等等。' THN'行,它们都需要从批处理中提取并发送到OUTPUT。(+ - 与上一个问题相同)
第三,虽然顺序第二步,但是“年龄”中的最后一个数字。在“THN'之前的主要表格数据的列线,需要附加到提取的THN'在它下面的直线(在这种情况下,图7,13和18)这些需要添加到它们各自的THN线。请参阅下面的预期输出,其中在两个C03 104'之后插入了年龄。每行中的变量。
如果没有' THN'在给定批次中的行,应忽略整个批次,没有输出,并考虑下一批次(以' 1(P1)'再次开始)。
上述批次预期的正确输出是:
CO3 104 7 11.4 6.7 .0230 164 2 4 1 3 2 0 0 0 0
CO3 104 13 17.5 12.2 .1044 265 6 28 2 25 8 15 3 0 0
CO3 104 18 21.6 15.9 .2142 220 8 47 2 45 6 19 20 0 0
从中可以看出,顶行的两个变量是在输出THN数据行的开头插入的。然后将从输入批次中读取的年龄数字插入其各自的THN行,然后附加其余的THN行数据。
我前段时间的努力但没有更新如下:
while ( my $line = <INPUT> ) {
if($line =~ /\s{6,11}(\w{1}\d{1}\w{0,5})\s{0,5}(\d{3})/) {
my @c_no = "$1,$2\n";
foreach (@c_no) {
print OUTPUT $_;
}
if ($line =~ /^(\s{1}THN)(\s{1,3}\d{0,2}.\d)(\s{1,3}\d{0,2}.\d)(\s{1,2}\d{0,1}.\d{4})(\s{1,2}\d{2,4})
(\s{2,3}\d{1,2})(\s{1,6}\d{1,4})(\s{1,2}\d{1,2})(\s{1,5}\d{1,4})(\s{1,4}\d{1,4})
(\s{1,4}\d{1,4})(\s{1,4}\d{1,4})(\s{1,4}\d{1,4})(\s{1,4}\d{1,4})|(^1(P1))/x){
print OUTPUT "$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14\n";
}
}
}
非常感谢建议,指导和帮助。
答案 0 :(得分:1)
使用split
将每一行分隔为以空格分隔的字段更为简单,如果您为标题行中的两个字段维护状态变量,则非常简单,第一个字段完全为数字的任何行的年龄。然后,所有必要的是在以THN
请注意,最简单的方法是将输入文件的名称作为参数传递给命令行。然后你要做的就是从<>
读取。所有的打开和错误处理都已经为您完成了
您要求的输出格式相当深奥。我看不到列宽的任何模式,我必须编写自定义printf
格式来重新创建它。如果您需要其他内容,则每个输出行中的所有值都在@data
数组中,您可以根据需要使用该数组
use strict;
use warnings 'all';
my ($c1, $c2, $age);
while ( <> ) {
next unless /\S/;
my @fields = split;
if ( $fields[0] eq '1(P1)' ) {
($c1, $c2) = @fields[10,11];
}
elsif ( $fields[0] !~ /\D/ ) {
$age = $fields[0];
}
elsif ( $fields[0] eq 'THN' ) {
my @data = ( $c1, $c2, $age, @fields[1..13] );
printf "%4s %5s %5d %5.1f%5.1f%7.4f%5d%4d%7d%3d%6d%5d%5d%5d%5d%5d\n", @data;
}
}
C03 104 7 11.4 6.7 0.0230 164 2 4 1 3 2 0 0 0 0
C03 104 13 17.5 12.2 0.1044 265 6 28 2 25 8 15 3 0 0
C03 104 18 21.6 15.9 0.2142 220 8 47 2 45 6 19 20 0 0
答案 1 :(得分:0)
我复制并修改了您的示例数据,因此我们没有进行过非常好的测试。我打印到STDOUT进行测试,但这应该很容易改变。
诀窍是要认识到你已经进行了行匹配,这对于正则表达式以及其他处理很有用,这对于普通的旧代码来说可能更好。因此,构建一个小循环,并以相同的优先级处理这些行(这对于检测文件中的错误非常重要 - 不要试图过多地嵌套)。放入一些状态变量来帮助跟踪接下来发生的事情,并确保适当地重置它们。
另外,我在你的示例代码中注意到的一件事是,如果时间间隔和数字正确的话,你花了很多钱。在这种情况下,这几乎肯定是浪费时间,因为关键是&#34; THN&#34;在线的开头。处理文本的一个技巧是关注你真正需要的东西,并使用.*
来处理其他东西。这样,线路噪音或语法错误或一些奇怪的格式化故障不会搞砸你的程序。 (有时候.*
变成[^"]*
或者其他什么,但你明白了......)
my $line_prefix, $have_age_col, $age_col;
while (<>) {
if (/^1\(P1\).*\s(?P<two_vars>\w+\s+\w+)\s+PROCESSED .* TIME .* KSINA=.*$/) {
# Start new section
$line_prefix = $+{two_vars};
$have_age_col = 0;
$age_col = undef;
}
if (/^AGE /) {
$have_age_col = 1;
}
if ($have_age_col && /^\s{0,5}(\d+)/) {
$age_col = substr " ".$1, -5;
}
if (/^THN /) {
die "THN encountered without header"
unless $line_prefix;
die "THN encountered without age column"
unless $have_age_col and $age_col;
s/^THN \s*//;
s/\s+$//;
my $output = "$line_prefix $age_col $_\n";
print STDOUT $output;
}
}