0

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

我的数据是

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  
4

3 回答 3

0

这是使用 perl 单行的解决方案:

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

在 perl 中添加 -i 选项可以直接修改原始文件。

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

您可以使用 s/match/replace/ 语法搜索和替换...

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,因此该|符号用于表示“或”。

正则表达式是一种强大的搜索和替换方式,许多工具和语言都支持它。值得在网上找到一个教程来更好地理解这种语法。

于 2013-03-02T12:41:45.590 回答
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。

于 2013-03-02T03:39:12.570 回答
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
于 2013-03-02T03:15:42.797 回答