【问题标题】:Replace column between patterns in one file from another file从另一个文件替换一个文件中模式之间的列
【发布时间】:2018-11-21 19:21:19
【问题描述】:

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

文件1

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

文件2

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 并将其替换为模式 1 和模式 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 中。此外,文件 2 中两种模式之间的线条。

我确信使用 FNR=NR 之类的东西,我应该能够同时处理这两个文件。任何帮助都会很好地继续进行。

【问题讨论】:

标签: awk


【解决方案1】:

根据您的问题和您提到的 (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 中什么都不会发生,只是用空字符串替换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 2012-04-13
    • 2016-07-12
    • 2023-03-07
    • 2018-01-22
    • 2013-05-19
    • 2017-05-12
    相关资源
    最近更新 更多