从另一个文件替换一个文件中的模式之间的列

时间:2018-11-21 19:21:19

标签: awk

我正在尝试编写读取文件1的shell脚本,并从该文件中获取特定列。并将file2中的列替换为从两个模式之间的file1中提取的列。

File1

Line1
Line2
.
LineN
ATOM C1 C2 C3
ATOM P23 HI IKJ
ATOM S23 JSK SN
BOND
Many lines
END

File2

Few Lines
Pattern1
1 C -9.2429 -1.3783 -9.5091 C.3 1 LIG1 0.0555
2 C -10.5865 -0.8658 -8.9679 C.3 1 LIG1 0.0529
3 N -11.3072 -0.5779 -10.1774 N.am 1 LIG1 -0.2940
Patttern2
Lines

我想从文件1中获取列$ 2,并将其替换为pattern1和pattern 2之间的file2中的列$ 2。

输出

Few Lines
Pattern1
1 C1 -9.2429 -1.3783 -9.5091 C.3 1 LIG1 0.0555
2 P23 -10.5865 -0.8658 -8.9679 C.3 1 LIG1 0.0529
3 S23 -11.3072 -0.5779 -10.1774 N.am 1 LIG1 -0.2940
Patttern2
Lines

到目前为止,我已经尝试了几件事。

awk '($1=="ATOM") {print $2}' file1
awk '/pattern1/{flag=1; next} /pattern2/{flag=0} flag' file2

我可以将列2存储在file1中。另外,file2的两个模式之间的线。

我确信使用FNR = NR之类的东西,我应该能够同时处理两个文件。任何帮助都将有助于进一步进行。

1 个答案:

答案 0 :(得分:0)

根据您的问题并提到(FNR == NR)解决方案,您可以使用以下AWK:

awk '
( FNR==NR && /^ATOM / ) { atoms[++atomn]=$2; }
( FNR!=NR && /^Patttern2$/ ) { doreplace=0; }
doreplace { $2=atoms[++atomn]; }
( FNR!=NR && /^Pattern1$/ ) { doreplace=1; atomn=0; }
FNR!=NR
' file1 file2

在处理图元文件和数据文件时,我更喜欢这样:

awk '
BEGIN {
  if ( ARGC != 3 ) exit(1);
  while ( getline < ARGV[2] ) if ( $0 ~ /^ATOM / ) atoms[++atomn]=$2;
  ARGC=2;
}
/^Patttern2$/ { doreplace=0; }
doreplace { $2=atoms[++atomn]; }
/^Pattern1$/ { doreplace=1; atomn=0; }
1
' file2 file1

两者都可以处理您提供的输入。输出:

Few Lines
Pattern1
1 C1 -9.2429 -1.3783 -9.5091 C.3 1 LIG1 0.0555
2 P23 -10.5865 -0.8658 -8.9679 C.3 1 LIG1 0.0529
3 S23 -11.3072 -0.5779 -10.1774 N.am 1 LIG1 -0.2940
Patttern2
Lines

两者都假定在图元文件(file1)和数据文件(file2)中,ATOM的数量和模式之间的行数完全相同。如果您无法验证这一点,那么我将添加逻辑以观察它不会遍历已分配的数组元素。但是在AWK中什么也不会发生,只是用空字符串代替。