如果使用awk / sed将一列的值为null,则替换其他列中的值

时间:2012-01-07 17:13:39

标签: linux sed awk

我试图通过替换以“:”分隔的2列的值来修改制表符分隔文件,其中一列中有空值:

从这个文件开始:

id1 id2 pos1    pos2
749 2847443 21  13517135
862 2821796 21  13571669
997     21  13636494
1095    2821826 21  13661335
1131        21  13678797

我想修改第2列以获取此信息:

id1 id2 pos1    pos2
749 2847443 21  13517135
862 2821796 21  13571669
997 21:13636494 21  13636494
1095    2821826 21  13661335
1131    21:13678797 21  13678797

问题还在于没有空格(“”)表示空值。 现在,当它为空时,我甚至无法用第3列替换第2列的值......

我尝试过使用sed:

sed -e 's/\t\t/\t$3\t/g' input.txt > output

哪个有效,但它只是替换文本'$ 3'而我找不到如何替换$ 3:$ 4的值。

我也试过awk:

awk 'BEGIN {
  IFS = OFS = "\t"
 }
{
    for (column = 2; column <= NF; ++column) {
    if ($column == "") {
        $column = $3
    }
 }    
 print 
}         
'
input.txt > output

但这也不起作用(它实际上没有使用“”也没有“”......)

你能帮帮我吗? 谢谢。

2 个答案:

答案 0 :(得分:3)

检查空值实际上很容易。但我不太了解这个要求。哪列可以为空?在你的awk脚本中,你有来自$ 2-&gt; $ NF的循环,如果有空列,你没有设置为“:”分隔值,但设置为$ 3。 3美元的价值是多少?

我假设只有$ 2(column2)可以为null,那么下面的awk行应该可以完成这项工作。

 awk -F'\t' -vOFS='\t' '!$2{$2=$3":"$4}1' file

<强>测试

<ff is your input file>

kent$  awk -F'\t' -vOFS='\t' '!$2{$2=$3":"$4}1' ff          
id1     id2     pos1    pos2
749     2847443 21      13517135
862     2821796 21      13571669
997     21:13636494     21      13636494
1095    2821826 21      13661335
1131    21:13678797     21      13678797

要清楚地看到它,我们可以将输出传递给列命令:

kent$  awk -F'\t' -vOFS='\t' '!$2{$2=$3":"$4}1' ff|column -t
id1   id2          pos1  pos2
749   2847443      21    13517135
862   2821796      21    13571669
997   21:13636494  21    13636494
1095  2821826      21    13661335
1131  21:13678797  21    13678797

希望它对你有所帮助。

答案 1 :(得分:2)

查看您发布的文本之前/之后

B:    997       21  13636494
A:    997   21:13636494 21  13636494

如果为空,则要替换第二列 使用3rd + '**:**' + 4th column,对吧?

所以去吧:

sed 's/\(.*\)\t\t\(.*\)\t\(.*\)/\1\t\2:\3\t\2\t\3/g' testfile

匹配

的行
  

某些标签选项卡

并将其替换为

  

第1栏标签第3栏:第4栏标签第3栏标签第4栏

示例:

$ cat testfile
749 2847443 21  13517135
862 2821796 21  13571669
997     21  13636494
1095    2821826 21  13661335
1131        21  13678797

$ sed 's/\(.*\)\t\t\(.*\)\t\(.*\)/\1\t\2:\3\t\2\t\3/g' testfile
749 2847443 21  13517135
862 2821796 21  13571669
997 21:13636494 21  13636494
1095    2821826 21  13661335
1131    21:13678797 21  13678797

注意:这只会查找缺少的第二列,正如您所谈到的那样

PS:如果您认为这可以回答您的问题,请不要忘记将其标记为正确答案