Linux:如果同一行中的另一列以特定字符开头/结尾,则替换特定列

时间:2013-03-02 02:55:26

标签: linux replace

我想在linux shell脚本中有条件地替换一些列。

Mydata是

ID         chr pos ver  
rs1234      1 12312 b1  
rs1245      1 21312 b1  
chr1:7576:D 1 22312 b1  
rs1002      1 34535 b1  
chr1:2434:D 1 34534 b1  
MER:1222    1 54645 b1  
rs2123      1 45645 b1 

如果第一列以“MER”开头或以“D”结尾,我想用“NA”替换第三列。 因此最终文件将如下所示

ID         chr pos    ver  
rs1234      1 12312   b1  
rs1245      1 21312   b1  
chr1:7576:D 1 **NA**  b1  
rs1002      1 34535   b1  
chr1:2434:D 1 **NA**  b1  
MER:1222    1 **NA**  b1  
rs2123      1 45645   b1  

3 个答案:

答案 0 :(得分:0)

您可以使用awk完成此操作,如下所示:

# awk '{if(NR!=1&&($1~/^MER/||$1~/D$/)){$3="N/A"} print $0}' INPUT > OUTPUT

使用您的样本数据提供以下输出:

ID         chr pos ver  
rs1234      1 12312 b1  
rs1245      1 21312 b1  
chr1:7576:D 1 N/A b1
rs1002      1 34535 b1  
chr1:2434:D 1 N/A b1
MER:1222 1 N/A b1
rs2123      1 45645 b1 

如果要保留格式并且列的宽度是固定的,则可以改为使用printf语句:

# awk '{if(NR!=1&&($1~/^MER/||$1~/D$/)){$3="N/A"} printf("%-As %Bs %Cs %Ds\n",$1,$2,$3,$4)}' INPUT > OUTPUT

用表示所需列宽的整数替换A,B,C和D.例如:

# awk '{if(NR!=1&&($1~/^MER/||$1~/D$/)){$3="N/A"} printf("%-11s  %1s  %5s %2s\n",$1,$2,$3,$4)}' INPUT > OUTPUT

给出:

ID          chr   pos ver
rs1234       1  12312 b1
rs1245       1  21312 b1
chr1:7576:D  1    N/A b1
rs1002       1  34535 b1
chr1:2434:D  1    N/A b1
MER:1222     1    N/A b1
rs2123       1  45645 b1

答案 1 :(得分:0)

以下是sed

的解决方案
sed -e 's/\(\(MER:[0-9]\+\|[0-9:]D\)\s\+[0-9]\+\s\+\)[0-9]\+\(.*\)/\1**NA**\3/g' INPUTFILE

生成

ID         chr pos ver  
rs1234      1 12312 b1  
rs1245      1 21312 b1  
chr1:7576:D 1 **NA** b1  
rs1002      1 34535 b1  
chr1:2434:D 1 **NA** b1  
MER:1222    1 **NA** b1  
rs2123      1 45645 b1

但是awk可能就是去这里的方式。或者perl。

答案 2 :(得分:0)

这是使用perl one-liner的解决方案:

perl -pe 's/^(MER:.+?|.+?:D)(\s+\d+\s+)(\d+)(.*)$/$1$2**NA**$4/' foo.txt

将-i选项添加到perl以直接修改原始文件。

以下是上述示例的更详细分类:

您可以使用s / match / replace / syntax ...

进行搜索和替换
s/^(MER:.+?|.+?:D)(\s+\d+\s+)(\d+)(.*)$/$1$2**NA**$4/
^^                                     ^            ^

括号用于捕获要在替换中使用的匹配组。

s/^(MER:.+?|.+?:D)(\s+\d+\s+)(\d+)(.*)$/$1$2**NA**$4/
   ^_____________^^_________^^___^^__^
         $1           $2      $3   $4

只有正则表达式匹配才会发生替换,因此括号中的第一个组确定您的情况下的匹配项。由于您希望以MER:开头或以:D结尾,因此|符号用于表示“或”。

正则表达式是一种强大的搜索和替换方式,并且在许多工具和语言中都受支持。值得在线查找教程以更好地理解这种语法。