처음 두 행이 단일 열(즉, 연속 문자열)과 같은 다음 파일이 있습니다. 열로 분할하고 "*" 문자를 "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