String Perl:比较两个文件的两个字符串

String Perl:比较两个文件的两个字符串,string,perl,file,compare,String,Perl,File,Compare,我有两个CSV文件。两者都有一个包含相同数据的列,不同之处在于一个文件在该列中包含的数据多于另一个文件 我只想打印出file2的行,其中该列中包含与另一个文件中相同的字符串 例如: file1 App_Int1 SID_bla1 App_Int2 SID_bla2 App_Int_4 SID_bla4 文件2 SID_bla1 hello bye ... SID_bla2 good bad ... SID_bla5 h

我有两个CSV文件。两者都有一个包含相同数据的列,不同之处在于一个文件在该列中包含的数据多于另一个文件

我只想打印出
file2
的行,其中该列中包含与另一个文件中相同的字符串

例如:

file1

App_Int1     SID_bla1
App_Int2     SID_bla2
App_Int_4    SID_bla4
文件2

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla5     hey       ho     ....
SID_bla4     hi        cheers ...
我希望输出像这样

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...
由于文件1不包含
SID_bla5
,因此将不会打印包含
SID_bla5
的行

这是我的代码,但它不起作用,有人能给我一些提示吗

#!C:\Perl\bin\perl
use strict;
use warnings;

my $file = $ARGV[0] || die "Need to get CSV file on the command line\n";
my $mystring = "";

open(my $data, '<', $file) || die "Could not open '$file' $!\n";
my $newfile = "fooNew3.txt";
open(FILE2, ">", $newfile) || die "Could not open file";

my $file2 = "export.txt";
open(my $data2, '<', $file2) || die "Could not open '$file2' $!";

my $mystring2 = "";
my $line2;
my %filehash;
my @fields2 = "";

while ($line2 = <$data2>) {
  chomp $line2;

  @fields2 = split(";", $line2);
  while (my $line = <$data>) {
    chomp $line;

    my @fields = split(";", $line);
    if ($filehash{ $fields2[0] } eq $fields[1]) {
      # if the first column of file2 is identical with the second column of file1
      # then output the identical string and the second column of file2
      # which belongs to the first column of file2 (which is the identical string)

      print FILE2 join ';', "$fields[1]; $filehash{$fields2[0]} $fields2[1] \n";
    }

你在设计这个问题

$ awk 'NR == FNR {a[$2]; next}$1 in a' file1.txt file2.txt
SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...
如果要使用Perl,请使用
-ap
调用它,以便在每行上自动拆分和自动循环并打印

如果您的数据是
-分隔,例如

file1.txt

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...
App_Int1;希德·布拉1
App_Int2;锡德布拉2
应用程序4;希德布拉4
file2.txt

SID_bla1     hello     bye    ...
SID_bla2     good      bad    ...
SID_bla4     hi        cheers ...
SID_bla1;你好再见;。。。
希德·布拉2;好,;坏;。。。
锡德布拉5;嘿呵;。。。。
锡德布拉4;你好干杯
您可以将字段分隔符设置为

$ awk -F';' 'NR == FNR {a[$2]; next}$1 in a' file1.txt file2.txt
SID_bla1;hello;bye;...
SID_bla2;good;bad;...
SID_bla4;hi;cheers;...

作为perl脚本,您的代码可以简化为以下内容:

#!C:\Perl\bin\perl
use strict;
use warnings;

die "Usage: $0 File1 File2\n" if @ARGV != 2;

my $file2 = pop;

my %seen;
while (<>) {
    my @F = split;
    $seen{$F[1]}++;
}

local @ARGV = $file2;
while (<>) {
    my @F = split;
    print if $seen{$F[0]};
}
#!C:\Perl\bin\Perl
严格使用;
使用警告;
如果@ARGV!=2.
my$file2=pop;
我看到的百分比;
而(){
我的@F=分裂;
$seen{$F[1]}++;
}
local@ARGV=$file2;
而(){
我的@F=分裂;
如果$SEED{$F[0]},则打印;
}

虽然您没有很好地描述它,但我认为您需要的是
file2
中的所有行,它们的第一列与
file1
的第二列中的任何值匹配。这个简短的Perl程序将为您实现这一点

我假设文件中的字段由空格或制表符的任意组合分隔。它的工作原理是从
file1
中的数据构建一个散列,每个记录的第二列中出现的每个字符串都有一个真值。这就是第一个文件所需要的全部内容

然后打开并处理
file2
。使用散列检查每行中的第一个字段,如果有相应的散列元素,则打印该行

use strict;
use warnings;
use autodie;

my $fh;
my %wanted;

open $fh, '<', 'file1.txt';
while (<$fh>) {
  my @fields = split;
  $wanted{$fields[1]} = 1;
}

open $fh, '<', 'file2.txt';
while (<$fh>) {
  my @fields = split;
  print if $wanted{$fields[0]};
}

我不认为你的意思是OP的代码可以简化成那样?毕竟他说他写的东西不管用。我还希望您为命令行程序保留
@F
。大写字母表示全局变量,
my@F
完全错误!不@Borodin,不是他的文字代码,而是他的意图:)。从命令行接受两个文件,处理每个文件,输出结果。作为99.9%的规则,我同意为全局变量或更具体的常量保留大写字母。但是,我认为这是一种特殊情况,在这种情况下,连接到autosplit
-a
标志对于熟悉命令行解析的任何人来说都是一种使代码更加自我记录的方法。如果它有一个特殊的标志,就像使用
$^I
进行就地编辑一样,我会使用它,但这可能会更好。但是您写道,“您的代码可以简化为以下内容”。这甚至没有暗示其意图。我知道
@F
来自何方,但我认为,以牺牲所有其他人为代价“为熟悉命令行解析的任何人”编写自我文档是错误的。一个简单的
@fields
是对allYes的自我记录,我是他的代码的化身。他的脚本想要的代码。也许在程序员们逐字思考的世界里,拟人化并不总是被认为是它的本意,但我不认为在这种情况下,一些松散的语言是有害的。当然,我不打算简化和复制他的代码的破坏性,但我可以理解它的意图,而无需实际阅读细节。自行车仍然是自行车,即使它缺少一个轮子,一个刹车片,齿轮生锈了,我们大多数人都能认出它是自行车,而不需要仔细检查:)我用gawk试过,但它也不起作用,我怎么能让它打印到另一个文件中?我的专栏是用英文分开的semicolons@user3507732如果你真的希望有人帮你解析,也许你应该放一些实际数据的样本?嗨,veryhungrymike,这对示例数据来说效果很好,但对实际数据集不起作用,因为它太大了,我想…你好,Borodin,在代码的最后一行“如果需要打印${$fields[0]};“我总是得到错误:在打印中使用未初始化的值$uu。我有一个关于$want{$fields[1]}=1;//值1被赋予file1.txt的2.列,这意味着什么?@user3507732:您必须在
循环时更改了
。请打开另一个问题并显示新代码的全部内容。”