【问题标题】:Replace values from other columns if value of one column is null using awk/sed如果一列的值为空,则使用 awk/sed 替换其他列的值
【发布时间】:2012-01-08 02:06:45
【问题描述】:

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

从这个文件开始:

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

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

我尝试过使用 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

但这也不起作用(实际上它既不使用 "" 也不使用 " "...)

你能帮帮我吗? 谢谢。

【问题讨论】:

    标签: linux sed awk


    【解决方案1】:

    检查空值实际上很容易。但我不太了解这个要求。哪一列可以为空?在您的 awk 脚本中,您从 $2->$NF 循环,如果有空列,您没有设置为“:”分隔值,而是使用 $3 设置。 $3 为空怎么办?

    我假设只有 $2 (column2) 可以为空,那么下面的 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
    

    希望对你有帮助。

    【讨论】:

    • 这行得通(没有-v,只有-OFS)非常感谢您的帮助!
    【解决方案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
    

    即匹配具有

    的行

    something tabtab something tabsomething

    替换成

    1st-column tab 3rd-column:4th-column tab 3rd-column tab 4th-column

    示例:

    $ 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:如果您认为这回答了您的问题,请不要忘记将其标记为正确答案

    【讨论】:

    • 嗨,sed 代码不起作用(它没有更改输入文件),所以我将使用 Kent 的 awk 代码,但感谢您的代码和解释。我仍然想知道为什么它不应该工作,但我的文字可能有些奇怪......
    猜你喜欢
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 2013-10-29
    相关资源
    最近更新 更多