次の行の列形式で最初の行を変更し、*を数字に置き換えて列間操作を実行するにはどうすればよいですか?

次の行の列形式で最初の行を変更し、*を数字に置き換えて列間操作を実行するにはどうすればよいですか?

最初の 2 つの行には、単一の列 (つまり連続文字列) などの次のファイルがあります。列に分割し、「*」文字を「x」数字に置き換えて、4行目と5行目に科学的表記法と列形式を指定したいと思います。

0.001000000*********************************************
0.061059059-3524.927327218-3524.938421865***************
0.121118118 -887.564833130 -887.569649256-6250.350946527
0.181177177 -387.169559377 -387.173137963-2743.981985633
0.241236236 -223.812193853 -223.815321341-1504.799155086
0.301295295 -134.073058536 -134.075910507 -924.916305653
0.361354354  -76.668692929  -76.671412688 -612.480371134

行1、2、3には、単一の列があるかのように連続する2つの列があるという同じ問題があります(その間にスペースを入れたい)。また、sqrt((sqrt($2 ^ 2 + $4 ^ 2) + $2) / 2) のような列間で複雑な作業を行いたいと思います。

予想される結果:

0.001000000 -3524.927327218 -3524.938421865 -6250.350946527
0.061059059 -3524.927327218 -3524.938421865 -6250.350946527
0.121118118  -887.564833130  -887.569649256 -6250.350946527
0.181177177  -387.169559377  -387.173137963 -2743.981985633
0.241236236  -223.812193853  -223.815321341 -1504.799155086
0.301295295  -134.073058536  -134.075910507  -924.916305653
0.361354354   -76.668692929   -76.671412688  -612.480371134

私の問題を解決する方法があるかどうかを知りたいです。

ベストアンサー1

私が見るには2つの明確な問題があるようです。

  • 完成すべき不完全な行
  • 区切りなしで数字を追加しました。

これは1回のawk呼び出しで可能になるかもしれませんが、単純化のために1つの作業に対して1回呼び出します。

あなたの入力/出力の例に基づいて、あなたの数字は常に小数点以下9桁であると仮定します。

「区切りなし」問題の処理

awk '{
         while ($0 ~ /[0-9]+\.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][^ ]/) {
             $0=gensub(/([0-9]+\.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])([^ ])/, "\\1 \\2", $0)
        }
        print
      }' input.txt > first_step.txt

注:gawkバージョンが4.0以上の場合[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]に置き換えると、[0-9]{9}次のようになります。

awk '{
         while ($0 ~ /[0-9]+\.[0-9]{9}[^ ]/) {
             $0=gensub(/([0-9]+\.[0-9]{9})([^ ])/, "\\1 \\2", $0)
        }
        print
      }' input.txt > first_step.txt

(読みやすくなりますか?)これはfirst_step.txt次のようになります。

0.001000000 *********************************************
0.061059059 -3524.927327218 -3524.938421865 ***************
0.121118118 -887.564833130 -887.569649256 -6250.350946527
0.181177177 -387.169559377 -387.173137963 -2743.981985633
0.241236236 -223.812193853 -223.815321341 -1504.799155086
0.301295295 -134.073058536 -134.075910507 -924.916305653
0.361354354  -76.668692929  -76.671412688 -612.480371134

「*」を次の行の値に置き換えます。

これも達成するのが少し難しいです。これらの「*」行はファイルの先頭にのみ現れると仮定します。まず、各行に4つのフィールドを持つようにします。

awk '/\*/ {
              a=""
              for (i=1; i < 5; i++) {
                  if (i < NF) a=a" "$i
                  else a=a" ***************"
              }
              print a; next
           }
           {print}' first_step.txt > second_step.txt

出力入力second_step.txt

 0.001000000 *************** *************** ***************
 0.061059059 -3524.927327218 -3524.938421865 ***************
0.121118118 -887.564833130 -887.569649256 -6250.350946527
0.181177177 -387.169559377 -387.173137963 -2743.981985633
0.241236236 -223.812193853 -223.815321341 -1504.799155086
0.301295295 -134.073058536 -134.075910507 -924.916305653
0.361354354  -76.668692929  -76.671412688 -612.480371134

今楽しい部分は...

awk 'BEGIN{first_lines=0}
     /\*/ {for (i=1; i<NF+1;i++) a[NR, i]=$i; next}
     first_lines != 1 {for (i=1; i<NF+1;i++) {a[NR, i]=$i};
                       for (i=NR-1; i > 0; i--) {
                           for (j=1; j < NF +1; j++) {
                               if (a[i, j] ~ /^\**$/) a[i, j] = a[i+1, j]
                           }
                       }
                       for (i=1; i < NR+1; i++) {
                           for (j=1; j < NF +1; j++) {
                               printf("%16s", a[i, j])
                           }
                           printf("\n")
                       }
                       first_lines = 1
                       next
                      }
                      {for (i=1;i<NF+1; i++) printf("%16s", $i)
                       printf("\n")
                      }' second_step.txt > output.txt

出力:

     0.001000000 -3524.927327218 -3524.938421865 -6250.350946527
     0.061059059 -3524.927327218 -3524.938421865 -6250.350946527
     0.121118118  -887.564833130  -887.569649256 -6250.350946527
     0.181177177  -387.169559377  -387.173137963 -2743.981985633
     0.241236236  -223.812193853  -223.815321341 -1504.799155086
     0.301295295  -134.073058536  -134.075910507  -924.916305653
     0.361354354   -76.668692929   -76.671412688  -612.480371134

おすすめ記事