Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.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 gsub根据不同的gsub条件同时生成多个列?_Bash_Loops_Awk_Gsub - Fatal编程技术网

Bash gsub根据不同的gsub条件同时生成多个列?

Bash gsub根据不同的gsub条件同时生成多个列?,bash,loops,awk,gsub,Bash,Loops,Awk,Gsub,我有一个包含以下数据的文件- 输入- A B C D E F A B B B B B C A C D E F A B D E F A A A A A A F A B C B B B 如果从第2行开始的任何其他行与第1行具有相同的字母,则应将其更改为1。基本上,我试图找出任何一行与第一行有多相似 期望输出- 1 1 1 1 1 1 1 1 B B B B C A 1 1 1 1 1 1 D E F A 1 A A A A 1 1 1 1 B B B 第一行已全部变为1,因为它与自身相同(显然)

我有一个包含以下数据的文件-

输入-

A B C D E F
A B B B B B
C A C D E F
A B D E F A
A A A A A F
A B C B B B
如果从第2行开始的任何其他行与第1行具有相同的字母,则应将其更改为1。基本上,我试图找出任何一行与第一行有多相似

期望输出-

1 1 1 1 1 1
1 1 B B B B
C A 1 1 1 1
1 1 D E F A
1 A A A A 1
1 1 1 B B B
第一行已全部变为1,因为它与自身相同(显然)。在第二行中,第一列和第二列与第一行相同(
ab
),因此它们成为
11
。其他行也是如此

我已经编写了下面的代码来完成这个转换-

for seq in {1..1} ; #Iterate over the rows (in this case just row 1)
do 
    for position in {1..6} ; #Iterate over the columns
    do 
        #Define the letter in the first row with which I'm comparing the rest of the rows
        aa=$(awk -v pos=$position -v line=$seq 'NR == line {print $pos}' f) 
        #If it matches, gsub it to 1 
        awk -v var=$aa -v pos=$position '{gsub (var, "1", $pos)} 1' f > temp
        #Save this intermediate file and now act on this
        mv temp f 
    done 
done
正如您可以想象的,这是非常缓慢的,因为嵌套循环非常昂贵。我的真实数据是一个60x10000矩阵,这个程序在上面运行大约需要2个小时


我希望你能帮我摆脱内环,这样我就可以一步完成所有6个GSUB。也许把它们放在自己的阵列中?我的
awk
技能还不太好。

您可以使用这个更简单的awk命令来完成这项工作,因为我们避免了shell中的嵌套循环,也避免了嵌套循环中重复调用awk:

awk '{for (i=1; i<=NF; i++) {if (NR==1) a[i]=$i; if (a[i]==$i) $i=1} } 1' file

1 1 1 1 1 1
1 1 B B B B
C A 1 1 1 1
1 1 D E F A
1 A A A A 1
1 1 1 B B B
awk'{for(i=1;i输入

$ cat f
A B C D E F
A B B B B B
C A C D E F
A B D E F A
A A A A A F
A B C B B B
所需的o/p

$ awk 'FNR==1{split($0,a)}{for(i=1;i<=NF;i++)if (a[i]==$i) $i=1}1' f
1 1 1 1 1 1
1 1 B B B B
C A 1 1 1 1
1 1 D E F A
1 A A A A 1
1 1 1 B B B

  • for(i=1;i
    ++
    为了简单!而且我确信它更快:)这就像一个魔咒。使我的整个程序快了3.5倍。我有程序的第二部分,将行中的数字相加。也就是说,这个输出将得到6,2,4,2,2,3。你的程序可以在这一步中调整以得到这些值吗?我应该单独问这个问题吗?这非常有效,是JUt与@anubhava.+1的解一样快。@VarunM很高兴知道。同样的问题,我有一个程序的第二部分,将行中的数字相加。也就是说,对于这个输出,你会得到6,2,4,2,2,3。你的程序能在这一步自己调整以得到这些值吗?接受这个问题是因为a中的解释很深入阿努巴瓦的回答同样好。
    $ awk 'FNR==1{split($0,a)}{for(i=1;i<=NF;i++)if (a[i]==$i) $i=1}1' f
    1 1 1 1 1 1
    1 1 B B B B
    C A 1 1 1 1
    1 1 D E F A
    1 A A A A 1
    1 1 1 B B B
    
           a[1] = A 
           a[2] = B
           a[3] = C 
           a[4] = D  
           a[5] = E  
           a[6] = F
    
    $ awk 'FNR==1{split($0,a)}{s=0;for(i=1;i<=NF;i++)if(a[i]==$i)s+=$i=1;print $0,s}' f
    1 1 1 1 1 1 6
    1 1 B B B B 2
    C A 1 1 1 1 4
    1 1 D E F A 2
    1 A A A A 1 2
    1 1 1 B B B 3