BASH - 使用for循环和If语句更改第2列中的信息

时间:2016-08-30 08:43:49

标签: bash loops if-statement awk multiple-columns

我有以下标签分隔文件:

ms1_table2

我们的想法是修改第7列(包含)和结尾之间的信息,对于每一行,如果第7列和第8行:

  • 等于“0 0”:不要修改

  • 等于“1 1”:不要修改

  • 等于“1 2”或“2 1”:更改为“2 2”

  • 等于“2 2”:不要修改

以下列(9和10,然后是11和12,13和14,依此类推......)相同。

我开始使用命令提取我想要处理的列:

  

awk'{for(i = 7; i< = NF; i ++)printf $ i“”; print“”}'test.ped> tmp_test.txt

然后我想在if语句中使用for循环,使用这种通用格式:

A1    A1    0       0       1       1       0 0     0 0     2 2     1 2
A2    A2    0       0       1       1       1 1     1 1     0 0     1 2
A3    A3    0       0       1       2       1 1     1 1     0 0     2 2
A4    A4    0       0       1       1       1 1     0 0     0 0     1 2

但我被困在这里。一般格式是逻辑的还是有更快的方法来做同样的事情?我正朝着正确的方向前进吗?

预期输出(在合并初始文件的前6列和我进行子集化和修改的列之后)是:

for i between 7 and the end (for (i = 7; i <= NF)):
    if i and i+1 == “1 2”:
        replace by “2 2”
    elif i and i+1 == “2 1”:
        replace by “2 2”
    else
        pass
    i=i+2 (increase i to do the same for the next double columns)

感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

$ awk '{$1=$1;for(i=7;i<=NF;i+=2) if($i""$(i+1)=="1""2" || $i""$(i+1)=="2""1") {$i=2;$(i+1)=2} print}' test
A1 A1 0 0 1 1 0 0 0 0 2 2 2 2
A2 A2 0 0 1 1 1 1 1 1 0 0 2 2
A3 A3 0 0 1 2 1 1 1 1 0 0 2 2
A4 A4 0 0 1 1 1 1 0 0 0 0 2 2

{
    $1=$1                 # break the record (for even output)
    for(i=7;i<=NF;i+=2)   # the loop increase by 2s
        if($i""$(i+1)=="1""2" || $i""$(i+1)=="2""1") {
            $i=2;$(i+1)=2 # reset col values if 1,2 OR 2,1
        } 
    print                 # print record, changed or not
}

答案 1 :(得分:1)

Awk是你的朋友。

awk -v FS='\t' -v OFS='\t' '{for(i=7;i<=NF;i++) \
 {if($i ~ /^[ 2]*[1]{1}[ 2]*$/){$i="2 2"}}}1'  file

应该这样做。

答案 2 :(得分:1)

听起来你只需要:

documentId

但是您的示例输入/输出真的没有帮助演示您的文字所描述的内容,并且我认为您的字段确实都是按标签分隔的,就像您说它们是如此的猜测一样。

答案 3 :(得分:0)

从你的问题看,下面的一对列是空格分隔的(第7和第8),(第9和第10),(第11和第12),(第13和第14)。而其他人则是分开的。如果是这种情况,你可以不用循环来做。

awk '{sub("1 2","2 2",$0);sub("2 1","2 2",$0); print;}' <filename>