이것은 내 샘플 텍스트 파일입니다.
[s] [K]
1 900
2 100
3 200
8 1000
1 80
55 12
6 90000
5 1
열 2에서 최대값을 찾고 열 1에서 해당 값을 찾은 다음 열 1의 모든 요소에서 해당 값을 빼야 합니다.
내가 원하는 출력은 이것이다
[s] [K]
-5 900
-4 100
-3 200
2 1000
-5 80
49 12
0 90000
-1 1
이건 내 단편이야
awk 'function abs(x) {return x<0?-x:x}
FNR==1 { $1=$1; print; next }
{if(max<$2){max=$2;line=$1}}{print $1-line "\t"$2}' test.txt
어쨌든 이것은 나에게 올바른 결과를 제공하지 않습니다. 또한 열 2의 가장 작은 값이 동일한 값을 갖기를 원합니다.
답변1
데이터를 두 번 통과해야 하며, 먼저 최소값과 최대값을 찾은 다음 계산을 수행해야 합니다.
awk 'BEGIN { OFS = "\t" }
FNR == NR { if (FNR > 1 && (min == "" || $2 < min)) { min = $2; minval = $1 }
if (FNR > 1 && (max == "" || $2 > max)) { max = $2; maxval = $1 }
next }
FNR == 1 { print "[s (-max)]", "[s (-min)]", "[K]"; next }
{ print $1 - maxval, $1 - minval, $2 }' file file
주어진 데이터에 대해 다음이 생성됩니다.
[s (-max)] [s (-min)] [K]
-5 -4 900
-4 -3 100
-3 -2 200
2 3 1000
-5 -4 80
49 50 12
0 1 90000
-1 0 1
이 awk
코드에는 4개의 블록이 있으며 여기에 입력 파일을 전달합니다.두 배. 첫 번째 블록( BEGIN
)은 단순히 출력 필드 구분 기호를 탭으로 설정합니다.
두 번째 블록( )은 파일을 처음 통과하는 동안 각 행에 대해 실행되며 두 번째 열( sum ) 의 최대값과 최소값 및 첫 번째 열( sum ) 의 해당 값을 FNR == NR
추적합니다 . 필요에 따라 업데이트합니다 . 이 블록의 끝에서 현재 입력된 스크립트의 나머지 부분을 건너뛰는 데 사용됩니다.max
min
maxval
minval
next
NR
현재 레코드의 전체 시퀀스 번호("줄 번호") FNR
이지만 현재 파일의 번호와 같습니다. 입력 파일을 처음으로 전달할 때와 동일합니다 NR
.FNR
FNR == 1
세 번째 블록( )은 두 번째 패스 파일에서 첫 번째 라인을 읽었을 때 실행됩니다. 제목만 출력합니다. 첫 번째 열의 값 minval
에서 합계 값을 뺀 값을 계산하므로 새 열 머리글을 추가합니다.maxval
마지막 블록은 무조건적이며 파일을 두 번째로 통과하는 동안 두 번째 줄을 실행하고 데이터의 실제 계산과 출력을 수행합니다.
다음과 같이 파이프하면 약간 더 예쁜 출력을 얻을 수 있습니다 column -s $'\t' -t
.
[s (-max)] [s (-min)] [K]
-5 -4 900
-4 -3 100
-3 -2 200
2 3 1000
-5 -4 80
49 50 12
0 1 90000
-1 0 1
답변2
$ cat tst.awk
BEGIN { OFS="\t" }
NR==1 { next }
NR==2 { maxVal = $2 }
NR==FNR {
if ($2 >= maxVal) {
maxSth = $1
maxVal = $2
}
next
}
{ print (FNR>1 ? ($1 - maxSth) : $1) , $2 }
$ awk -f tst.awk file file
[s] [K]
-5 900
-4 100
-3 200
2 1000
-5 80
49 12
0 90000
-1 1
답변3
어쩌면 이런 게 있지 않을까요?로그 처리 파일을 두 번.
awk 'NR==FNR && NR>1 { max_col2=( max_col2>$2?max_col2:$2 ); max[$2]=$1;
min_col1=( min_col1>$1?min_col1:$1 ); min[$1]=$2; }
NR!=FNR && FNR>1{ print $1-max[max_col2], $2-min[min_col1]; }' OFS='\t' infile infile
-5 888
-4 88
-3 188
2 988
-5 68
49 0
0 89988
-1 -11