입력 샘플
file name
0.00 -1.0000 number1
0.00 -0.8000 number2
0.00 -0.6000 number3
0.00 -0.4000 number4
0.00 -0.2000 number5
0.00 0.0000 number6
0.00 0.2000 number7
0.00 0.4000 number8
0.00 0.6000 number9
0.00 0.8000 number10
0.00 1.0000 number11
0.02 -1.0000 number12
0.02 -0.8000 number13
0.02 -0.6000 number14
0.02 -0.4000 number15
0.02 -0.2000 number16
0.02 0.0000 number17
0.02 0.2000 number18
0.02 0.4000 number19
0.02 0.6000 number20
0.02 0.8000 number21
0.02 1.0000 number22
0.04 -1.0000 number23
0.04 -0.8000 number24
0.04 -0.6000 number25
0.04 -0.4000 number26
0.04 -0.2000 number27
0.04 0.0000 number28
0.04 0.2000 number29
0.04 0.4000 number30
0.04 0.6000 number31
0.04 0.8000 number32
0.04 1.0000 number33
표적
(인용하다열/필드awk 명명법에서는 $1 = 필드 1입니다.
보시다시피 3개의 데이터가 있습니다. 각 블록에서 $1은 상수 값과 같습니다. $1 = 상수인 각 블록에 대해 $2 = 0을 중심으로 $3를 대칭적으로 교환하고 싶습니다. 결과는 다음과 같은 원하는 출력이 됩니다.
원하는 출력
file name
0.00 -1.0000 number11
0.00 -0.8000 number10
0.00 -0.6000 number9
0.00 -0.4000 number8
0.00 -0.2000 number7
0.00 0.0000 number6
0.00 0.2000 number5
0.00 0.4000 number4
0.00 0.6000 number3
0.00 0.8000 number2
0.00 1.0000 number1
0.02 -1.0000 number22
0.02 -0.8000 number21
0.02 -0.6000 number20
0.02 -0.4000 number19
0.02 -0.2000 number18
0.02 0.0000 number17
0.02 0.2000 number16
0.02 0.4000 number15
0.02 0.6000 number14
0.02 0.8000 number13
0.02 1.0000 number12
0.04 -1.0000 number33
0.04 -0.8000 number32
0.04 -0.6000 number31
0.04 -0.4000 number30
0.04 -0.2000 number29
0.04 0.0000 number28
0.04 0.2000 number27
0.04 0.4000 number26
0.04 0.6000 number25
0.04 0.8000 number24
0.04 1.0000 number23
배경 컨텍스트
실제 입력에서는 $1이 {0.00..0.02..15.0} 순서로 계속됩니다. 또한 각 블록에서 $2는 {-14..0.2..14} 형식으로 이동합니다. 따라서 총 751개의 블록이 있으며 각 블록에는 자체적으로 141개의 라인(또는 각 블록 앞에 추가 헤더/빈 라인을 포함하여 142개의 라인)이 포함됩니다.
따라서 751개의 블록을 하나씩 통과하여 단일 블록의 중간선(각 블록의 71행 또는 72행)을 중심으로 대칭적으로 해당 블록의 임의 값인 $3를 반영할 수 있는 스크립트가 있다면 매우 도움이 될 것입니다. 각 블록 위의 빈 줄 포함).
감사합니다!
답변1
이것을 다음으로 표시합니다.세게 때리다, 그러나 awk가 언급되었으므로 사용할 수 있기를 바랍니다.
$ awk -vn=0 'NR == 1 {print; next}
$0 != "" { k = $1; a[n] = $2; b[n] = $3; n++ }
$0 == "" { for (i = 0; i < n ; i++) {
printf "%s %s %s\n", k, a[i], b[n-i-1]; }
n=0; print }' < data
첫 번째 줄( NR == 1
)에서는 인쇄하고 계속 진행합니다.
그런 다음 비어 있지 않은 줄의 경우 두 번째 및 세 번째 필드를 배열에 로드하고 a
, 빈 줄의 경우 b
배열을 순서대로 반복하고 역순으로 인쇄한 후 마지막으로 카운터를 재설정합니다.a
b
n
이는 (1) 미러 포인트가 실제로 중간에 있다고 가정합니다. (2) 각 블록의 첫 번째 필드는 항상 동일합니다(코드와 마찬가지로). (3) 각 블록 뒤에는 빈 줄이 있습니다. 추가 빈 줄은 중요하지 않습니다. 빈 줄이 없으면 끝에 하나를 추가하십시오.