假设您有一堆包含以下行的文件:
{yellow_forest_ant|monsters_insects:2|Yellow forest ant|forestant||5|||10|100|||2|2|15||insect|||||||||}; {small_rabid_dog|monsters_dogs:1|Small rabid dog|forestdog||6|||10|90|||2|2|||canine|||||||||};
并且您希望在第5个和第6个字段之间插入三个字段,其中一些新内容取决于现有字段的内容。
你会如何以自动化的方式做到这一点? 在现有文本文件的行内插入一些动态内容。
我的解决方案(在Perl中):
while(<>) {
if (/\{(.+?)\};/) {
my @v= $1 =~ /([^\|\{\}]*?|\{\{.*?\}\})\|/g;
my @output= (@v[0..4], guessMonsterClass($v[1]), $uniques{$v[0]}, '',@v[5..24]);
print '{'.join('|',@output)."|};\n";
} else { print; }
}
虽然我的解决方案有效,但效果不佳。 请改进!
答案 0 :(得分:1)
如果您的输入不包含转义垂直条,则可以使用split
和splice
:
while (<>) {
if (/\{(.+?)\};/) {
my @v = split /\|/, $1, -1;
splice @v, 5, 0, guessMonsterClass($v[1]), $uniques{$v[0]}, '';
print '{', join('|', @v), "};\n";
} else {
print;
}
}
注意使用-1作为split
的LIMIT来保持空字段的结尾。捕获所有空字段,因此您无需在print
中添加额外的竖线。
答案 1 :(得分:0)
摆脱卷曲的眨眼({};
),为你的字段命名(完整,合理):
F1|F2|F3|F4|F5|F6 yellow_forest_ant|monsters_insects:2|"Yellow forest ant"|forestant||5 small_rabid_dog|monsters_dogs:1|"Small rabid dog"|forestdog||6
my $dbh = DBI->connect( 'dbi:CSV:', "", "", {
f_dir => "../data"
, csv_sep_char => '|'
, PrintError => 0
, RaiseError => 1
});
my $sth = $dbh->prepare('SELECT * FROM monsters.txt');
$sth->execute;
while(my @row = $sth->fetchrow_array()) {
print '|', join( '|', @row ), "|\n";
}
$sth = $dbh->prepare("UPDATE monsters.txt SET F5 = F6 * 2 WHERE F4 = 'forestant'");
$sth->execute;
$sth = $dbh->prepare('SELECT * FROM monsters.txt');
$sth->execute;
while(my @row = $sth->fetchrow_array()) {
print '|', join( '|', @row ), "|\n";
}
输出:
|yellow_forest_ant|monsters_insects:2|Yellow forest ant|forestant||5| |small_rabid_dog|monsters_dogs:1|Small rabid dog|forestdog||6| |yellow_forest_ant|monsters_insects:2|Yellow forest ant|forestant|10|5| |small_rabid_dog|monsters_dogs:1|Small rabid dog|forestdog||6|
答案 2 :(得分:-1)
我建议你用awk处理它。