다음 행의 열 형식에서 첫 번째 행을 변경하고 *를 숫자로 바꾸고 열 간 작업을 수행하는 방법은 무엇입니까?

다음 행의 열 형식에서 첫 번째 행을 변경하고 *를 숫자로 바꾸고 열 간 작업을 수행하는 방법은 무엇입니까?

처음 두 행이 단일 열(즉 연속 문자열)인 것처럼 포함된 다음 파일이 있습니다. 이를 열로 분리하고 "*" 문자를 과학 표기법과 열 형식을 네 번째 및 다섯 번째 행으로 제공하는 "x" 숫자로 바꾸고 싶습니다.

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

제 생각에는 두 가지 매우 다른 문제가 있는 것 같습니다.

  • 채워야 할 불완전한 줄
  • 구분 기호 없이 추가된 숫자

이는 아마도 하나의 awk 호출로 가능하지만 단순화를 위해 각 작업에 대해 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

관련 정보