我有一个包含以下文本(File1)的文件-
1SER CA 1 1.401 0.040 0.887
2GLN CA 2 1.708 -0.155 1.002
3ALA CA 3 1.870 -0.103 0.662
4GLU CA 4 1.829 0.274 0.695
我有一个类似文本的单独文件(file2)-
1MET CA 1 17.704 15.987 17.370
2ARG CA 2 17.811 16.145 17.712
3ARG CA 3 17.634 16.267 18.034
4TYR CA 4 17.465 16.615 18.002
我的目标是将file1中2-4范围内的字符替换为file2的2-4中的数据。
期望输出-
1MET CA 1 1.401 0.040 0.887
2ARG CA 2 1.708 -0.155 1.002
3ARG CA 3 1.870 -0.103 0.662
4TYR CA 4 1.829 0.274 0.695
也就是说,file2的2-4个字符放置在file1的2-4字节中。
我知道我可以用cut -c 2-4 | sed ...
缩小所需的区域,但我无法从单独的文件中“读取”数据并进行替换。
我有一种感觉,它可能更容易在awk,但没有列为基础的答案请。它需要一个基于文件中字符范围的解决方案(在本例中是2-4)。
添加了示例
解决方案应该也能做到这一点- file1-
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
文件2-
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
产出-
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
发布于 2016-09-09 15:25:24
基于paste
和cut
的解决方案
$ paste -d '' <(cut -c1 file1) <(cut -c2-4 file2) <(cut -c5- file1)
1MET CA 1 1.401 0.040 0.887
2ARG CA 2 1.708 -0.155 1.002
3ARG CA 3 1.870 -0.103 0.662
4TYR CA 4 1.829 0.274 0.695
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
与变量:
$ s=10
$ e=25
$ paste -d '' <(cut -c1-$((s-1)) file1) <(cut -c"$s"-"$e" file2) <(cut -c$((e+1))- file1)
1SER CA 1 17.704 0.040 0.887
2GLN CA 2 17.811 -0.155 1.002
3ALA CA 3 17.634 -0.103 0.662
4GLU CA 4 17.465 0.274 0.695
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
发布于 2016-09-09 13:42:09
如果要替换列,只需存储来自file1的数据并将其替换为file2:
$ awk 'FNR==NR {col1[FNR]=$1; col2[FNR]=$2; next} {$1=col1[FNR]; $2=col2[FNR]}1' f1 f2
1SER CA 1 17.704 15.987 17.370
2GLN CA 2 17.811 16.145 17.712
3ALA CA 3 17.634 16.267 18.034
4GLU CA 4 17.465 16.615 18.002
还可以存储前两列的值,然后“手动”替换它们,如删除带有awk或sed的列中所示。
$ awk 'FNR==NR {data[FNR]=$1 OFS $2; next} {$0=gensub(/(\s*\S+){2}/,data[FNR],1)}1' f1 f2
1SER CA 1 17.704 15.987 17.370
2GLN CA 2 17.811 16.145 17.712
3ALA CA 3 17.634 16.267 18.034
4GLU CA 4 17.465 16.615 18.002
如果您只想替换某些字符,请使用substr()
提取这些字符:
$ awk -v start=2 -v len=3 'FNR==NR{data[FNR]=substr($0, start, len); next} {$0=substr($0, 1, 2) data[FNR] substr($0, start+len+1)}1' f2 f1
AABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
这就是:
awk -v start=2 -v len=3 \
'FNR==NR{data[FNR]=substr($0, start, len); next} # store from the start-th to the (start+len)-th chars
{$0=substr($0, 1, start) data[FNR] substr($0, start+len+1)} # replace those
1' f2 f1 # print what was created
发布于 2016-09-09 14:17:52
如果“列”和“字节”实际上指的是“字符”,那么:
$ cat tst.awk
BEGIN {
split(range,r,/-/)
repS = r[1]
repL = r[2] - r[1] + 1
befL = repS - 1
aftS = repS + repL
}
NR==FNR { rep[NR] = substr($0,repS,repL); next }
{ print substr($0,1,befL) rep[FNR] substr($0,aftS) }
$ awk -v range='2-4' -f tst.awk file2 file1
1MET CA 1 1.401 0.040 0.887
2ARG CA 2 1.708 -0.155 1.002
3ARG CA 3 1.870 -0.103 0.662
4TYR CA 4 1.829 0.274 0.695
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ awk -v range='10-25' -f tst.awk file2 file1
1SER CA 1 17.704 0.040 0.887
2GLN CA 2 17.811 -0.155 1.002
3ALA CA 3 17.634 -0.103 0.662
4GLU CA 4 17.465 0.274 0.695
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
AAAAAAAAABBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAA
上面使用了示例的级联作为输入文件。
https://stackoverflow.com/questions/39412898
复制相似问题