Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash是一种基于索引列表比较两个不同文件中特定列的方法_Bash_Awk - Fatal编程技术网

Bash是一种基于索引列表比较两个不同文件中特定列的方法

Bash是一种基于索引列表比较两个不同文件中特定列的方法,bash,awk,Bash,Awk,我有两个选项卡分隔的文件,共1708行,列数不同。我的目标是比较所有行存储的值,但只比较一些特定列的值。我有两个列表,其中包含要比较的列的编号;这里有一个例子: 菲拉➝ col_ind_A=[12,20,24,55] 文件➝ col_ind_B=[14,28,35,79] 这里,应将文件A的第12列与文件B的第14列、文件A的第20列与文件B的第28列进行比较,依此类推。如果文件A的值为0,而文件B的值为0,我想在该位置修改文件C(文件A的副本),然后存储文件B的值(不是0): 我已经看到比

我有两个选项卡分隔的文件,共1708行,列数不同。我的目标是比较所有行存储的值,但只比较一些特定列的值。我有两个列表,其中包含要比较的列的编号;这里有一个例子:

  • 菲拉➝ col_ind_A=[12,20,24,55]
  • 文件➝ col_ind_B=[14,28,35,79]
这里,应将文件A的第12列与文件B的第14列、文件A的第20列与文件B的第28列进行比较,依此类推。如果文件A的值为0,而文件B的值为0,我想在该位置修改文件C(文件A的副本),然后存储文件B的值(不是0):

我已经看到比较列通常是用awk完成的,但是我对bash非常陌生,我不知道如何迭代两个文件的行,同时迭代列索引列表并指示要比较的列位置。欢迎提出任何建议

如果有帮助的话,我将展示一个R代码,它正好做到了这一点(它太慢了):

for(i在1:1708中){#行
对于(j in 1:31946){#cols
如果(fileA[i,col_ind_A[j]='0'&&fileA[i,col_ind_A[j]!=fileB[i,col_ind_B[j]]){

fileC[i,col_ind_A[j]一个执行此操作的perl脚本:

!/usr/bin/env perl
严格使用;
使用警告;
使用自动模具;
使用功能qw/say/;
使用列表::Util qw/pairs/;
#根据需要进行调整。
我的@columns=(12=>14,20=>28,24=>35,55=>79);
我的($filea_name,$fileb_name)=@ARGV;
@columns=成对映射{$\ 1}@columns;

打开我的$filea,“首先逐行加入文件,然后检查要检查的条件

# recreate input
cat >file1 <<EOF
col11 col12 col13
A C G
G 0 T
EOF
cat >file2 <<EOF
col13 col14 col15
A C G
G T T
EOF

paste file1 file2 |
awk '{ if ($2 == 0 && $2 != $6) $2=$6; print $1, $2 ,$3}'
我猜从
for(1:1708中的I){#rows
中,假设两个文件中的列数相同,您可能希望迭代所有列:

paste file1 file2 |
awk '{ 
   for (i=1;i<=NF/2;++i) if ($i == 0 && $i != $(i*2)) $i = $(i*2);
   for (i=1;i<=NF/2;++i) printf "%s%s", $i, i==NF/2?ORS:OFS; 
}'
粘贴文件1文件2|
awk'{

对于(i=1;i由于您要求提供
awk
解决方案,这里有一个简单的解决方案:

awk -v col_ind_A='12 20 24 55' -v col_ind_B='14 28 35 79' '
BEGIN { OFS="\t"
        split(col_ind_A, ciA)
        split(col_ind_B, ciB)
        while (getline <"FileB" > 0 && split($0, B) && getline <"FileA" > 0)
        {
            for (i in ciA) if ($ciA[i] == 0) $ciA[i] = B[ciB[i]]
            print >"FileC"
        }
      }'

您可以共享输入文件的示例记录吗?我会将文件转换为SQLite或其他db。为相关列编制索引以提高速度,并要求db引擎处理查询。最终将最终输出的格式重新设置为与数据文件类似的格式。@Armali您说得对,我刚刚解决了这个问题,谢谢。至于我的记录示例,它们是您创建的.ped文件sing PLINK,它们看起来与示例中完全相同,但有更多的行和列。我希望这会有所帮助。关于假设两个文件中的列数相同的问题,询问者写道:我有两个标签分隔的文件,共1708行,列数不同。我认为合并文件可能不是最好的主意,因为fileA有180000多列umns和fileB有30000多个,但无论如何,感谢awk位非常有用:)这看起来真的很好,是否可以将列也添加为包含“'12=>14,20=>28,24=>35,55=>79,”,因为通信数量超过30000。谢谢!
getline 0
应该是
(getline 0
。FileA也一样。R代码工作得非常完美,速度非常快。非常感谢!!
col11 col12 col13
A C G
G T T
paste file1 file2 |
awk '{ 
   for (i=1;i<=NF/2;++i) if ($i == 0 && $i != $(i*2)) $i = $(i*2);
   for (i=1;i<=NF/2;++i) printf "%s%s", $i, i==NF/2?ORS:OFS; 
}'
awk -v col_ind_A='12 20 24 55' -v col_ind_B='14 28 35 79' '
BEGIN { OFS="\t"
        split(col_ind_A, ciA)
        split(col_ind_B, ciB)
        while (getline <"FileB" > 0 && split($0, B) && getline <"FileA" > 0)
        {
            for (i in ciA) if ($ciA[i] == 0) $ciA[i] = B[ciB[i]]
            print >"FileC"
        }
      }'
for (i in 1:nrow(FileA))
{
    j = which(FileA[i, col_ind_A] == 0)
    FileC[i, col_ind_A[j]] = FileB[i, col_ind_B[j]]
}