Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux:如果同一行中的另一列开始/结束时具有特定字符,则替换特定列_Linux_Replace - Fatal编程技术网

Linux:如果同一行中的另一列开始/结束时具有特定字符,则替换特定列

Linux:如果同一行中的另一列开始/结束时具有特定字符,则替换特定列,linux,replace,Linux,Replace,我想有条件地替换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

我想有条件地替换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  

您可以使用
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

下面是一个使用
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。

这里有一个使用perl一行程序的解决方案:

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

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