SED固有の熱交換

SED固有の熱交換

Sedコマンドを使用して列4からAをRAに置き換えるにはどうすればよいですか? (この列の間には複数のスペースが含まれています。)

ATOM     32  P     A     2       6.882  -5.338   6.560  1.00  0.00           P  
ATOM     33  OP1   A     2       7.505  -5.970   7.750  1.00  0.00           O  
ATOM     34  OP2   A     2       5.404  -5.201   6.610  1.00  0.00           O  
TER

合格できるawk '{gsub("A","RA",$4)}1' a.txt > b.txt

ベストアンサー1

間隔が固定されている必要があるため、これはレイアウト全体が固定されていることを意味します。EREを有効にするには、GNU sedやOSX / BSD sedなどの-Eをサポートするsedを使用します。

$ sed -E 's/(.{17})A /\1RA/' file
ATOM     32  P     RA    2       6.882  -5.338   6.560  1.00  0.00           P
ATOM     33  OP1   RA    2       7.505  -5.970   7.750  1.00  0.00           O
ATOM     34  OP2   RA    2       5.404  -5.201   6.610  1.00  0.00           O
TER

または、POSIX sedを使用してください。

$ sed 's/\(.\{17\}\)A /\1RA/' file
ATOM     32  P     RA    2       6.882  -5.338   6.560  1.00  0.00           P
ATOM     33  OP1   RA    2       7.505  -5.970   7.750  1.00  0.00           O
ATOM     34  OP2   RA    2       5.404  -5.201   6.610  1.00  0.00           O
TER

編集:入力内容が一致しないようです。PDB標準@bushmanは以前に公開しましたが、そのような場合は、次のようにf[]ラベル/名前でフィールド配列を作成し、ラベル/名前で変更し(入力の相対位置ではなく)、印刷を使用できます。同じ固定幅フォーマット:

$ cat tst.awk
BEGIN {
    # Record Format (copied from http://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ATOM)
    #
    #                 COLUMNS        DATA  TYPE    FIELD        DEFINITION
    #                 -------------------------------------------------------------------------------------
    flds[++numFlds]="  1 -  6        Record name   ATOM  "
    flds[++numFlds]="  7 - 11        Integer       serial       Atom  serial number."
    flds[++numFlds]=" 13 - 16        Atom          name         Atom name."
    flds[++numFlds]=" 17             Character     altLoc       Alternate location indicator."
    flds[++numFlds]=" 18 - 20        Residue name  resName      Residue name."
    flds[++numFlds]=" 22             Character     chainID      Chain identifier."
    flds[++numFlds]=" 23 - 26        Integer       resSeq       Residue sequence number."
    flds[++numFlds]=" 27             AChar         iCode        Code for insertion of residues."
    flds[++numFlds]=" 31 - 38        Real(8.3)     x            Orthogonal coordinates for X in Angstroms."
    flds[++numFlds]=" 39 - 46        Real(8.3)     y            Orthogonal coordinates for Y in Angstroms."
    flds[++numFlds]=" 47 - 54        Real(8.3)     z            Orthogonal coordinates for Z in Angstroms."
    flds[++numFlds]=" 55 - 60        Real(6.2)     occupancy    Occupancy."
    flds[++numFlds]=" 61 - 66        Real(6.2)     tempFactor   Temperature  factor."
    flds[++numFlds]=" 77 - 78        LString(2)    element      Element symbol, right-justified."
    flds[++numFlds]=" 79 - 80        LString(2)    charge       Charge  on the atom."

    for (fldNr=1; fldNr<=numFlds; fldNr++) {
        fld = flds[fldNr]

        cols = substr(fld,1,16)
        gsub(/ /,"",cols)
        n = split(cols,begEnd,/-/)

        tag  = substr(fld,31,13)
        gsub(/ /,"",tag)

        tags[fldNr] = tag
        begs[tag] = begEnd[1]
        wids[tag] = begEnd[n] - begEnd[1] + 1

        # Uncomment this if interested in the values the arrays contain:
        # print "<" fldNr "><" tags[fldNr] "><" begs[tag] "><" wids[tag] ">" | "cat>&2"
    }
}

{
    for (fldNr=1; fldNr<=numFlds; fldNr++) {
        tag = tags[fldNr]
        f[tag] = substr($0,begs[tag],wids[tag])
        gsub(/^ +| +$/,"",f[tag])
    }
}

f["resName"] == "A" { f["resName"] = "RA" }     # this is where you can change a field by its tag/name

{
    for (fldNr=1; fldNr<=numFlds; fldNr++) {
        tag = tags[fldNr]
        printf "%-*s", wids[tag], f[tag]
    }
    print ""
}
$
$ awk -f tst.awk file
ATOM  32   P    RA  2    6.882   -5.338  6.560   1.00  0.00  P
ATOM  33   OP1  RA  2    7.505   -5.970  7.750   1.00  0.00  O
ATOM  34   OP2  RA  2    5.404   -5.201  6.610   1.00  0.00  O
TER

明らかに、これは今やっていることに比べて少し過剰ですが、覚えておくべき良い一般的なアプローチであり、関心のある分野について以前に議論した他のアプローチで発生する可能性がある問題を解決します。 。

おすすめ記事