我编写了一个perl脚本,它将3列拆分为标量,并使用正则表达式替换第二列中的各种值。这部分工作正常,如下所示。但是,我想要做的是更改第一列($ item_id为一系列连续数字,当$ item_id的原始(数值)值发生变化时重启。
例如:
123个
123个
123个
123个
2397
2397
2397
2397
8693
8693
8693
8693
将更改为类似的内容(在一列中):
1 2 3 4 1 2 3 4 1 2 3 4
这可以替换第一列或者是新的第四列。 我明白我可以通过一系列if-else语句来做这个并尝试过这个,但这似乎不适合我已经为我工作的while程序。 - 谢谢,汤姆谢泼德
open(DATA,"< text_to_be_processed.txt");
while (<DATA>)
{
chomp;
my ($item_id,$callnum,$data)=split(/\|/);
$callnum=~s/110/\%I/g;
$callnum=~s/245/\%T/g;
$callnum=~s/260/\%U/g;
print "$item_id\t$callnum\t$data\n";
} #End while
close DATA;
答案 0 :(得分:1)
基本步骤是:
在循环外部声明计数器和一个包含前一个$item_id
的变量。
在循环内你做三件事:
$item_id
与前一个my ($counter, $prev_item_id) = (0, '');
while (<DATA>) {
# do your thing
$counter = $item_id eq $prev_item_id ? $counter + 1 : 1;
$prev_item_id = $item_id;
print "$item_id\t$counter\t...\n";
}
不同,则将计数器重置为1,否则将其增加使用代码,这看起来与此类似(未经测试):
{{1}}
答案 1 :(得分:1)
这比你要求的更进一步......
这是代码。
use strict;
use warnings;
use autodie;
open(my $fh, "<", "text_to_be_processed.txt");
my %Callnum_Map = (
110 => '%I',
245 => '%T',
260 => '%U',
);
my %item_id_count;
while (<$fh>) {
chomp;
my($item_id,$callnum,$data) = split m{\|};
for my $search (keys %Callnum_Map) {
my $replace = $Callnum_Map{$search};
$callnum =~ s{$search}{$replace}g;
}
my $item_count = ++$item_id_count{$item_id};
print "$item_id\t$callnum\t$data\t$item_count\n";
}
通过使用散列,它不会假定数据按项目ID排序。所以,如果它看到......
123|foo|bar
456|up|down
123|left|right
789|this|that
456|black|white
123|what|huh
它会产生......
1
1
2
1
2
3
这是更强大的,假设您想要计算在整个文件中看到项ID的次数。如果你想连续看多少次,请使用Mortiz的解决方案。
答案 2 :(得分:0)
这是你在找什么?
open(DATA,"< text_to_be_processed.txt");
my $counter = 0;
my $prev;
while (<DATA>)
{
chomp;
my ($item_id,$callnum,$data)=split(/\|/);
$callnum=~s/110/\%I/g;
$callnum=~s/245/\%T/g;
$callnum=~s/260/\%U/g;
++$counter;
$item_id = $counter;
#reset counter if $prev is different than $item_id
$counter = 0 if ($prev ne $item_id );
$prev = $item_id;
print "$item_id\t$callnum\t$data\n";
} #End while
close DATA;