perl - 在 Perl 中编写和读取文件
问题描述
我正在尝试从具有以下结构( tbl_20180615.txt )的原始文件将主键构建到新文件中:
573103150033,0664,54,MSS02VEN*',INT,zxzc,,,,,
573103150033,0665,54,MSS02VEN,INT,zxzc,,,,,
573103150080,0659,29,MSS05ARA',INT,zxzc,,,,,
573103150080,0660,29,MSS05ARA ,INT,zxzc,,,,,
573103154377,1240,72,MSSTRI01,INT,zxzc,,,,,
573103154377,1240,72,MSSTRI01,INT,zxzc,,,,,
我启动我的perl Verify.pl
然后我发送参数,第一个是在新文件中构建主键的列数,在我必须发送文件名(原始文件)之后。
(验证.pl)
#!/usr/bin/perl
use strict;
use warnings;
my $n1 = $ARGV[0];
my $name = $ARGV[1];
$n1 =~ s/"//g;
my $n2 = $n1 + 1;
my %seen;
my ( $file3 ) = qw(log.txt);
open my $fh3, '>', $file3 or die "Can't open $file3: $!";
print "Loading file ...\n";
open( my $file, "<", "$name" ) || die "Can't read file somefile.txt: $!";
while ( <$file> ) {
chomp;
my @rec = split( /,/, $_, $n2 ); #$n2 sirve para armar la primary key, hacer le split en los campos deseados
for ( my $i = 0; $i < $n1; $i++ ) {
print $fh3 "@rec[$i],";
}
print $fh3 "\n";
}
close( $file );
print "Done!\n";
#########检查重复项
my ($file4) = qw(log.txt);
print "Checking duplicates records...\n\n";
open (my $file4, "<", "log.txt") || die "Can't read file log.txt: $!";
while ( <$file4> ) {
print if $seen{$_}++;
}
close($file4);
如果我发送以下指令
perl Verify.pl 2 tbl_20180615.txt
此代码使用以下结构构建一个名为“log.txt”的新文件,将原始文件 () 拆分为第一个参数给出的两列:( log.txt )
573103150033,0664,
573103150033,0665,
573103150080,0659,
573103150080,0660,
573103154377,1240,
573103154377,1240,
可以,但是如果我想读取新文件log.txt
以检查重复项,则它不起作用,但是如果我log.txt
在代码中的行之前注释行以生成文件(上面列出)(###### #########检查重复项###############) 启动代码的下一部分,它可以正常工作,给我两个重复的行,如下所示: (结果在命令行)
573103154377,1240
573103154377,1240
我该如何解决这个问题?
解决方案
我认为这可以满足您的要求。它在打印任何派生键之前构建一个唯一的派生键列表,使用哈希检查是否已经生成了一个键
请注意,我已经分配了值@ARGV
来模拟输入值。您必须在使用命令行输入运行程序之前删除该语句
#!/usr/bin/perl
use strict;
use warnings;
use autodie; # Handle bad IO statuses automatically
local @ARGV = qw/ 2 tbl_20180615.txt /; # For testing only
tr/"//d for @ARGV; # "
my ($key_fields, $input_file) = @ARGV;
my $output_file = 'log.txt';
my (@keys, %seen);
print "Loading input ... ";
open my $in_fh, '<', $input_file;
while ( <$in_fh> ) {
chomp;
my @rec = split /,/;
my $key = join ',', @rec[0..$key_fields-1];
push @keys, $key unless $seen{$key}++;
}
print "Done\n";
open my $out_fh, '>', $output_file;
print $out_fh "$_\n" for @keys;
close $out_fh;
输出log.txt
573103150033,0664
573103150033,0665
573103150080,0659
573103150080,0660
573103154377,1240
推荐阅读
- vue.js - vue.js v-for 从 2 个不同的列表中更改
- java - Jetty 9 + Spring Boot - 由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext
- css - 如何更改 Semantic UI React Dropdown 的边框颜色?
- java - 如何使用命令提示符在两个 jar 文件之间创建管道?
- c++ - 如何使用 boost/operators.hpp 自动生成 == 运算符?
- android - 我在加载插页式广告时不断收到此错误
- javascript - 如何声明对现有命名空间的引用,该命名空间可在运行时从 JavaScript 包中获得
- cordova - tel: 和 mailto: 链接仅在 iOS13 上不起作用
- javascript - 使用固定菜单调整锚点到其他页面
- python-3.x - 调试 any() 行时的 GeneratorExit 异常