1

わかりました。最初に、私が抱えている問題をより詳細に説明します。ここで 2 つの変数を設定しています。1 つはデータの 1 つの列をコピーし、もう 1 つはデータの複数の列をコピーします...

問題は、複数の列を整列させたまま、データの最初の列を複数の列の前に追加したいということです

ループは、ループを個別に Cmain にリダイレクトすると、私が望むことも実行します。しかし、私はそれらの両方にそれを行う必要があります

#copies first column of original car file to format the atom numbers

 FC=$(awk '{for (i=6; i<=21 ; i++)
 if (NR >= 6 && NR == i)
      print $1}' $carf)


 #copies and formats  the rest of the columns from the .incoor file and sets to variable Col

 col=$(awk '{for (j=6; j <= 21 ; j++)
 if (NR >= 6 && NR == j)
 printf  "%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", $2, $3, $4,
 "     XXXX", " 1", "    xx","  " $1"  ", "  0.000"}' $coor)

これは物事がうまくいかないところです

 #echos variables and appends to Cmain 
 echo  " $FC   $col" >> Cmain

何が起こっているかの例; 何らかの理由で、列の 2 番目のセットを取り、それらを下にシフトし、最初の行を上にシフトします...私が言ったように、それらを個別に行うと、列が整列し、すべてが桃色になります...データの最初の列がないことを除いて

 U1
U2
U3
U4
C1
C2
C3
C4
U5
U6
U7
U8
C5
C6
C7
C8       0.00000000       0.00000000      0.00000000     XXXX 1    xx  U  0.000
   0.00000000     4.43785037      4.86047726     XXXX 1    xx  U  0.000
   4.86047726     0.00000000      4.86047726     XXXX 1    xx  U  0.000
   4.86047726     4.43785037      0.00000000     XXXX 1    xx  U  0.000
   4.86047726     4.43785037      4.86047726     XXXX 1    xx  C  0.000
   4.86047726     0.00000000      0.00000000     XXXX 1    xx  C  0.000
   0.00000000     0.00000000      4.86047726     XXXX 1    xx  C  0.000
   0.00000000     8.87570074      0.00000000     XXXX 1    xx  U  0.000
   0.00000000    13.31355111      4.86047726     XXXX 1    xx  U  0.000
   4.86047726     8.87570074      4.86047726     XXXX 1    xx  U  0.000
   4.86047726    13.31355111      0.00000000     XXXX 1    xx  U  0.000
   4.86047726    13.31355111      4.86047726     XXXX 1    xx  C  0.000
   4.86047726     8.87570074      0.00000000     XXXX 1    xx  C  0.000
   0.00000000    13.31355111      0.00000000     XXXX 1    xx  C  0.000
   0.00000000     8.87570074      4.86047726     XXXX 1    xx  C  0.000

私が欲しいのは

  U1    0.00000000     0.00000 etc
  U2    0.00000000     4.43785037      4.86047726 .......
4

2 に答える 2

2

paste(1)コマンド を探しています。echoある文字列を別の文字列に接合することはできません (これは、実際に探しているもののようです。文字列 2 の各改行の前に、文字列 1 の次の行を挿入します)。

pasteただし、文字列ではなくファイルで動作しますが、Bash では簡単に回避できます。プロセス置換を使用するだけです。

#!/bin/bash

# Refactored into a function for maintainability and legibility
# Maybe you want to factor out the magical constants 6 and 21 somehow as well?
atoms () {
    awk '# Simplified script; apparently, you simply want lines 6 through 21
     NR==6,NR==21 { print $1 }' "$@"
}
# Ditto
cols () {
    awk '# Simplified this script as well
     NR==6,NR==21 {
       printf  "%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", $2, $3, $4,
               "     XXXX", " 1", "    xx","  " $1"  ", "  0.000"}' "$@"
}

paste <(atoms "$carf") <(cols "$coor")

ファイルが大きい場合は、21 行目以降で終了することで時間を大幅に節約できます。

NR==22 { exit }
于 2012-07-31T07:39:02.050 に答える
1

AWK スクリプトは、各ファイルの各行で6から 21 までカウントしています。これは必要ないと思います。行番号がその範囲内にあるかどうかをテストするだけだと思います。これが私が意味することの例です:

FC=$(awk 'NR >= 6 && NR <=21)
     print $1}' $carf)

ただし、実際に行う必要があるのは、2 つの AWK スクリプトを組み合わせて、最初のファイルの値を配列に保存し、2 番目のファイルの値を出力するときに配列の値を出力することです。

awk 'FNR == NR && FNR >= 6 && FNR <= 21 {    # first file
        carf[FNR] = $1
     }
     FNR == NR {
         next
     }
     FNR >= 6 && FNR <= 21 {    # second file
         printf  "%-4s%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", carf[FNR], $2, $3, $4,
             "     XXXX", " 1", "    xx","  " $1"  ", "  0.000"
     }' "$carf" "$coor"

echo(または)がないことに注意してくださいpaste

実際に出力にタブが必要な場合を除き、それらを省略してフィールド幅を調整し、必要な出力配置を得ることができます。

于 2012-07-31T07:58:14.087 に答える