line替换分割两边的给定上下文

时间:2016-04-15 16:13:51

标签: bash awk replace split

我正在尝试在分割的两侧给出一个替换给定上下文的行。这在python中看起来要容易得多,但我的整个管道都在bash中,所以我很想坚持像sed,awk,grep等工具。

例如:

split_0 = split('\t')[0]
split_1 = split('\t')[1]
if (a b c in split_0 AND w x y z in split_1):
    split_1 = split_1.replace('w x y z', 'w x_y z')

我可以使用awk做这样的分割:

awk -F '\t' '{print$1}'

但为了满足这两个条件,我不知道如何同时在双方这样做。任何帮助将不胜感激。

输入/输出示例: 这是一个例子,我有很多这样的规则,但基本上我想要做的是给出一个例子,我有" ex"在左侧和" ih g z"在右侧,我想用ih g z替换为ih g_z。

input: exam    ih g z ae m
output: exam    ih g_z ae m

我可以做一个残酷的像:

sed 's/\(.*ex.*\t.*\)ih g z\(.*\)/\1ih g_z\2/g' 

但这看起来很难看,我相信有更好的方法可以做到这一点。 *我不完全确定" \ t"在sed中以这种方式工作。

1 个答案:

答案 0 :(得分:1)

awk救援!

awk -F'\t' '$1~/ex/ && $2~/ih g z/{sub("g z","g_z")}1' file

字段1和2上的条件由制表符分隔符分隔,替换字符串(一次)。

如果您有一堆这些替换规则,最好不要在脚本中对它们进行硬编码

    $ awk -F'\t' -v OFS='\t' 'NR==FNR{lr[NR]=$1; rr[NR]=$2; 
                                      ls[NR]=$3; rs[NR]=$4; next}
                                     {for(i=1; i<=length(lr); i++) 
                                         if($1~lr[i] && $2~rr[i])
                                            {gsub(ls[i],rs[i],$2);
                                             print; 
                                             next}}1' rules file

111     2b2b2b
222     333u33u
4       bbb5az
9       nochange

其中

$ head rules file
==> rules <==
1       2       a       b
2       3       z       u
4       5       e       b

==> file <==
111     2a2a2a
222     333z33z
4       eee5az
9       nochange

注意到替换将仅针对第二个字段的第一个适用规则且多次。这两个文件都需要以制表符分隔。