在第一个分号后替换字符串,同时保留字符串

时间:2017-02-08 03:55:46

标签: shell awk sed

我有一个结果文件,值由; 分隔,如下所示:

  

137;的 AJP14028.1_VP35 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14037.1_VP35 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14352.1_VP35 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14846.1_VP35 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E

我想将第二个值( AJP14028.1_VP35 )更改为 AJP14028 ,而后面没有“.1_VP35”。结果将是:

  

137;的 AJP14028 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14037 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14352 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E
  137;的 AJP14846 ; HLA-A * 02:01; MVAKYDFLV; 0.79200; 0.35000; 0.87783; 0.99826; 0.30;< -E

有关如何做到这一点的任何想法?我试图用sed或awk来解决这个问题,但我还不熟悉它们。

4 个答案:

答案 0 :(得分:2)

使用该输入并关注第二个字段,您可以使用awk

$ awk 'BEGIN{FS=OFS=";"} {split($2, arr, /\.1/); $2=arr[1]} 1' file
137;AJP14028;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E 
137;AJP14037;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E 
137;AJP14352;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E 
137;AJP14846;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E 

说明:

  1. BEGIN{FS=OFS=";"}将FS和OFS设置为";"。这会将输入拆分为;字符,并将输出字段分隔符设置为相同的字符。
  2. {split($2, arr, /\.1/)在文字.1的模式上拆分第二个字段,并将结果放在数组中。
  3. $2=arr[1]是一个awk惯用法,用于将第二个字段$2重置为修剪后的值。副作用是总记录,$0使用输出字段分隔符OFS
  4. 重置
  5. 1最后是另一个尴尬 - 打印当前记录。
  6. 如果您只是要删除固定字符串.1_VP35(并且您不关心它是否特定于字段),您可以使用sed

    sed 's/\.1_VP35//' file
    

答案 1 :(得分:1)

awk '{sub(/.1_VP35/,"")}1' file

137;AJP14028;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14037;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14352;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14846;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E

答案 2 :(得分:0)

sed -r 's/(^[^.]*)(.[^;]*)(.*)/\1\3/g' inputfile
137;AJP14028;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14037;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14352;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E
137;AJP14846;HLA-A*02:01;MVAKYDFLV;0.79200;0.35000;0.87783;0.99826;0.30;<-E

这里:back referencing用于将输入行分为三组,由`()&#39;分隔。后来他们被称为&#34; \ 1&#34;等等。

第一组将从行的开头到第一个点匹配。 第二组将匹配字符串,后跟第一个点,直到第一个分号。 第三组将匹配其后的所有内容。

答案 3 :(得分:0)

这可能适合你(GNU sed):

 sed 's/\(;[^.]*\)[^;]*/\1/' file

对第一个;以及之后的所有内容(不是.)进行后向引用,然后从其上移除所有不是;的内容。