从一个制表符分隔的文件替换数组元素与哈希值从使用Perl另一个文件 [英] Substituting array elements from one tab delimited file with hash values from another file using Perl

查看:181
本文介绍了从一个制表符分隔的文件替换数组元素与哈希值从使用Perl另一个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在与它们对应的散列值的数组代替每个元素。为了更清楚:我有两个文件1)ref.tab 2)data.tab。
参考文件中包含类似数据:

  A一
b b
C C
D D

数据文件包含类似数据:

  1苹果红
2桔桔乙
3葡萄黑色C
4猕猴桃绿色ð

我想什么现在要做的使用Perl是:从ref.tab相应的值替代值的所有实例data.tab第4栏

我的code是如下:

 #!的/ usr / bin中/ perl的
使用严格的;
使用警告;
使用诊断;#定义文件,其中包含的参考值:
开放DFILE,ref.tab'或死亡无法打开数据文件;#存储每一列到数组:
我@caps;
我@small;
而(小于DFILE&GT){
    我@tmp =分流/ \\吨/年;
    推@帽,$ TMP [0];
    推@小,$ TMP [1];
}
打印加入('',@caps),\\ n;
打印加入('',@small),\\ n;#单独的阵列转换成散列:
我的%replaceid;
@replaceid {} @caps = @small;打印$ _ $ {replaceid $ _} \\ n表示(键%replaceid);#定义在列值将被替换的文件:
开放SFILE,output.tab'或死亡无法打开源文件;#在存储阵列所需的列:
我@ COL4;
而(小于SFILE&GT){
    我@ TMP1 =分流/ \\吨/年;
    推@ COL4,$ TMP1 [4];
}为$ _(0 .. $#COL4){
    如果($ _ = $键replaceid [$ COL4 [$ _]]){
        〜S / $ _ /值$ replaceid [$ COL4 [$ _] /克;
    }
}
打印@ COL4
关闭(DFILE);
关闭(SFILE);
出口;

以上程序会导致这个错误:

 未初始化值$ TMP1使用[3]中加入或replace.pl线4串。

如何解决?

新问题:

现在另一个问题。我想离开这个领域的空白,如果没有相应的替代品。这是如何任何想法可以这样做?即,

ref.tab

  A一
b b
C C
D D
量F f

data.tab:

  1苹果红
2桔桔乙
3葡萄黑色C
4猕猴桃绿色ð
5瓜黄色Ë
6香橼绿˚F

所需的输出:

  1苹果红
2桔桔b
3葡萄黑色C
4猕猴桃绿色ð
5瓜黄色
6香橼绿˚F

我怎样才能做到这一点?

新问题,2

我现在的 AWK 的解决方案有另外一个问题。它离开该字段为空,如果没有比赛,但我有4后附加列;所以每当有没有找到匹配,在第五列中的值被转移到了第四列。

  1苹果红甜美
2桔桔b酸味
3葡萄黑色C甜蜜
4绿色奇异果甜美Ð
5瓜甜黄
6香橼绿˚F酸

在第5行:在这里你可以看到发生了什么;在第5列中的值被转移到了第4列,其中有没有找到替代


解决方案

Perl的解决方案:

 使用严格的;
使用警告;#创建的文件句柄
打开我的$ REF,'<','ref.tab'或死亡$ !;
打开我的$ DATA,'<','data.tab'或死亡$ !;我的%replaceid;#初始化从REF文件您的HashMap
而(小于$ REF&GT){
    我($ K,$ V)=分流/ \\ s + /;
    $ replaceid {$ķ} = $ V;
}#读取数据文件
而(小于$ DATA>){
    我@tmp =分流/ \\ s + /;
    接下来,除非存在$ replaceid {$ TMP [3]}; #如果4 FLD存在于哈希
    $ TMP [3] = $ replaceid {$ TMP [3]}或下; #替换您当前使用的哈希值线
    打印连接(\\ t的,@tmp),\\ n; #打印您的当前行
}关闭$ REF;
接近$ DATA;


AWK解决方案:

 的awk'NR == FNR {a [$ 1] = $ 2;接下来} {$ 4 =(A [$ 4])一[$ 4]:} 1'OFS = \\ t的ref.tab data.tab


  • 我们完全读取ref.tab文件,并在有作为密钥值列1和列2哈希加载它。

  • 一旦ref.tab文件被读取,我们搬到data.tab文件和散列值代替第4列。

I would like to substitute each element in an array with their corresponding hash values. To make it more clear: I have two files 1) ref.tab 2) data.tab. The reference file contains data like:

A    a
B    b
C    c
D    d

The data file contains data like:

1    apple    red    A
2    orange    orange    B
3    grapes    black    C
4    kiwi    green    D

What I would like to do now using Perl is: Substitute all instances of values in column 4 of data.tab with the corresponding values from ref.tab.

My code is as follows:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

# Define file containing the reference values:
open DFILE, 'ref.tab' or die "Cannot open data file";

# Store each column to an array:
my @caps;
my @small;
while(<DFILE>) {
    my @tmp = split/\t/;
    push @caps,$tmp[0];
    push @small,$tmp[1];
}
print join(' ', @caps),"\n";
print join(' ', @small),"\n";

# convert individual arrays to hashes:
my %replaceid;
@replaceid{@caps} = @small;

print "$_ $replaceid{$_}\n" for (keys %replaceid);

# Define the file in which column values are to be replaced:
open SFILE,'output.tab' or die "Cannot open source file";

# Store the required columns in an array:
my @col4;
while(<SFILE>) {
    my @tmp1 = split/\t/;
    push @col4,$tmp1[4];
}

for $_ (0..$#col4) {
    if ($_ = keys $replaceid[$col4[$_]]){
        ~s/$_/values $replaceid[$col4[$_]]/g;
    }
}


print "@col4";
close (DFILE);
close (SFILE);
exit;

The above program results in this error:

Use of uninitialized value $tmp1[3] in join or string at replace.pl line 4.

What is the solution?

New issue:

Another issue now. I would like to leave the field blank if there is no respective replacement. Any idea on how this could be done? That is,

ref.tab

A   a
B   b
C   c
D   d
F   f

data.tab:

1   apple   red A
2   orange  orange  B
3   grapes  black   C
4   kiwi    green   D
5   melon   yellow  E
6   citron   green  F

Desired output:

1   apple   red a
2   orange  orange  b
3   grapes  black   c
4   kiwi    green   d
5   melon   yellow
6   citron   green  f

How can I do this?

New issue, 2

I have another issue now with the AWK solution. It does leave the field blank if there is no match, but I have additional columns after the 4th; so whenever there is no match found, the value in the fifth column gets shifted to the fourth column.

1 apple red a sweet
2 orange orange b sour
3 grapes black c sweet
4 kiwi green d sweet
5 melon yellow sweet
6 citron green f sour

On line 5: Here you can notice what happens; the value in 5th column gets shifted to the 4th column where there is no replacement found.

解决方案

Perl solution:

use strict;
use warnings;

# Create your filehandles
open my $REF , '<', 'ref.tab'  or die $!;
open my $DATA, '<', 'data.tab' or die $!;

my %replaceid;

# Initialize your hashmap from ref file
while (<$REF>) {
    my ($k, $v) = split /\s+/;
    $replaceid{$k} = $v;
}

# Read the data file
while(<$DATA>) {
    my @tmp = split /\s+/;
    next unless exists $replaceid {$tmp[3]};   # If 4th fld exists in hash
    $tmp[3] = $replaceid{$tmp[3]} or next;     # Replace your current line with hash value
    print join("\t", @tmp), "\n";              # Print your current line   
}

close $REF;
close $DATA;


AWK solution:

awk 'NR==FNR{a[$1]=$2;next}{$4=(a[$4])?a[$4]:""}1' OFS="\t" ref.tab data.tab

  • We read the ref.tab file completely and load it in a hash having column 1 as key and column 2 as value.
  • Once the ref.tab file is read, we move to data.tab file and substitute the 4th column with hash value.

这篇关于从一个制表符分隔的文件替换数组元素与哈希值从使用Perl另一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆