简体   繁体   English

用bash和awk解析约束

[英]Parsing restraints with bash and awk

I have restraints that look like 我的约束看起来像

G6N-D5C-?: (116.663, 177.052, 29.149) K87CD/E85CB/E94CB/H32CB/Q21CB
L12N-T11C-?: (128.977, 175.109, 174.412) K158C/H60C/A152C/N127C/Y159C(notH60C)
K14N-E13C-?: (117.377, 176.474, 29.823) E187CB/V78CB
A75N-Q74C-?: (123.129, 177.253, 23.513) V131CG1/V135CG1/V78CG1

and I need to convert them with output: 我需要将它们转换为输出:

assign (resid 5 and name C ) (resid 87 and name CD or resid 85 and name CB or resid 94 and name CB or resid 32 and name CB or resid 21 and name CB ) 3.5 2.5 8.5 ! G6N-D5C-?: (116.663, 177.052, 29.149) K87CD/E85CB/E94CB/H32CB/Q21CB
assign (resid 11 and name C ) (resid 158 and name C or resid 60 and name C or resid 152 and name C or resid 127 and name C or resid 159 and name C ) 3.5 2.5 8.5 ! L12N-T11C-?: (128.977, 175.109, 174.412) K158C/H60C/A152C/N127C/Y159C(notH60C)
assign (resid 13 and name C ) (resid 187 and name CB or resid 78 and name CB ) 3.5 2.5 8.5 ! K14N-E13C-?: (117.377, 176.474, 29.823) E187CB/V78CB
assign (resid 74 and name C ) (resid 131 and name CG1 or resid 135 and name CG2 or resid 78 and name CG1 ) 3.5 2.5 8.5 ! A75N-Q74C-?: (123.129, 177.253, 23.513) V131CG1/V135CG1/V78CG1

I have tried awk, but I couldn't figure out how to break up the array. 我尝试了awk,但是我不知道如何分解数组。 Please help me convert this, it is brutal to do by hand. 请帮我转换一下,手工做是残酷的。

You'll want to split the first word on - and examine the 2nd element. 您需要将第一个单词分割-并检查第二个元素。
Then split the last word on / and examine each element. 然后在/上分割最后一个单词并检查每个元素。

Assuming GNU awk, read carefully about split() and match() from http://www.gnu.org/software/gawk/manual/html_node/String-Functions.html#String-Functions 假设使用GNU awk,请从http://www.gnu.org/software/gawk/manual/html_node/String-Functions.html#String-Functions仔细阅读split()match()


Feeling generous: 感觉大方:

gawk '
  function extract(str, fmt,      m) {
    if (match(str, /^.([0-9]+)(.+)/, m)) printf fmt, m[1], m[2]
  }
  {
    split($1, a, /-/)
    extract(a[2], "assign (resid %d and name %s ) (")
    n = split($NF, a, /\//)
    sep = ""
    for (i=1; i<=n; i++) {
      extract(a[i], sep "resid %d and name %s ")
      sep = "or "
    }
    print ") 3.5 2.5 8.5 !", $0
  }
'

Here is one way using perl : 这是使用perl一种方法:

#!/usr/bin/perl 

use strict;
use warnings;
use autodie;

open my $fh, '<', 'restraints.file';

while (<$fh>) {
    my @values = map { /.(\d+)(\w+)/; $1, $2 } split '/', (split)[-1];
    my ( $resid, $name ) = /^[^-]+-.(\d+)(\w+)-/;
    print "assign (resid $resid and name $name ) (";
    print join ( " or ", 
        map  { "resid $values[$_] and name $values[$_ + 1]" } 
        grep { not $_ % 2 } 0 .. $#values 
    );
    print " ) 3.5 2.5 8.5 ! $_";
}

Output: 输出:

assign (resid 5 and name C ) (resid 87 and name CD or resid 85 and name CB or resid 94 and name CB or resid 32 and name CB or resid 21 and name CB ) 3.5 2.5 8.5 ! G6N-D5C-?: (116.663, 177.052, 29.149) K87CD/E85CB/E94CB/H32CB/Q21CB
assign (resid 11 and name C ) (resid 158 and name C or resid 60 and name C or resid 152 and name C or resid 127 and name C or resid 159 and name C ) 3.5 2.5 8.5 ! L12N-T11C-?: (128.977, 175.109, 174.412) K158C/H60C/A152C/N127C/Y159C(notH60C)
assign (resid 13 and name C ) (resid 187 and name CB or resid 78 and name CB ) 3.5 2.5 8.5 ! K14N-E13C-?: (117.377, 176.474, 29.823) E187CB/V78CB
assign (resid 74 and name C ) (resid 131 and name CG or resid 135 and name CG or resid 78 and name CG ) 3.5 2.5 8.5 ! A75N-Q74C-?: (123.129, 177.253, 23.513) V131CG1/V135CG1/V78CG1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM