Ubuntu 시스템에 다음 데이터 세트가 있습니다.
37.500 0.0000 0.005605
37.750 0.0000 -0.027858
38.000 0.0000 -0.060678
38.250 0.0000 -0.088557
38.500 0.0000 -0.109210
38.750 0.0000 -0.122482
39.000 0.0000 -0.129770
39.250 0.0000 -0.133190
39.500 0.0000 -0.134538
39.750 0.0000 -0.134015
40.000 0.0000 -0.129660
40.250 0.0000 -0.117858
40.500 0.0000 -0.094709
40.750 0.0000 -0.057622
41.000 0.0000 -0.006853
열 1의 38에서 40 사이에 있는 열 3의 최대값을 찾아야 합니다.
이것은 단지 샘플 데이터 세트입니다.
답변1
awk '$1 >= 38 && $1 <= 40 && $3 > max {max = $3; out = $0};
END {print out}' input.txt
참고: $3에는 양수 값이 없습니다. 여기서 38 <= $1 <= 40입니다. 이것이 출력이 빈 줄인 이유입니다. (왜요? max
기본값은 0이고 그 위에 음수 값이 하나도 없기 때문입니다.)
양수든 음수든 가장 높은 값을 원할 경우 max
$3에서 가능한 가장 작은 값보다 작은 값으로 초기화하세요. 예를 들어 -9999
:
$ awk -v max=-9999 '$1 >= 38 && $1 <= 40 && $3 > max {max = $3; out = $0};
END {print out}' input.txt
38.000 0.0000 -0.060678
또는 BEGIN
대신 블록을 사용하세요 -v
.
$ awk 'BEGIN {max=-9999};
$1 >= 38 && $1 <= 40 && $3 > max {max = $3; out = $0};
END {print out}' input.txt
38.000 0.0000 -0.060678
또는 Perl을 사용하여 예상치 못한 값으로 초기화하는 대신 $max가 정의되지 않았는지 테스트합니다.
$ perl -lane '
if ($F[0] >= 38 && $F[0] <= 40 && (!defined($max) || $F[2] > $max)) {
$max = $F[2];
$out = $_;
};
END { print $out }' input.txt
38.000 0.0000 -0.060678
답변2
"하나의 작업을 위한 하나의 도구"라는 Unix 정신에서 한 가지 해결책은 행 필터링을 사용한 awk
다음 정렬을 사용하는 것입니다 sort
.
awk '$1>=38 && $1<=40' test.txt | sort -n -k 3 -r | head -n 1
구체적으로 여기서는 세 번째 열을 사용하여 반전(가장 큰 값부터 시작)하고 행을 표시하는 -n
숫자 정렬을 사용하고 있습니다. 좋은 점은 처음 3개 값, 최소값 등으로 확장하는 것이 매우 쉽다는 것입니다.-k3
-r
head -n 1
답변3
sort
-> sed
해결책.
계속해서 일치하는 라인을 홀드 버퍼( /^(3[89]|40\.000)/h
)에 넣은 다음 마지막으로 홀드 + 패턴 버퍼( $x
)와 인쇄 패턴 버퍼( $p
)를 교체합니다.
$ sort -rk 3n test.txt |sed -nE '/^(3[89]|40\.000)/h;$x;$p'
38.000 0.0000 -0.060678
$
답변4
사용행복하다(이전 Perl_6)
~$ raku -e 'lines.map(*.words).grep(38 < *.[0] < 40).map(*.[2].Num).max.say;' file
또는 (확장 버전):
~$ raku -e 'my @a = lines>>.words; @a.=grep(38 < *.[0] < 40); @a.map(*.[2].Num).max.say;' file
위의 코드는 -0.088557
지정된 기준에 따라 단일(최대) 값인 Column_1을 반환합니다. 즉, lines
공백 구분 기호를 읽고 중단하여 words
38 과 40 사이의 열 1 값(0 인덱스 = )을 grep
찾은 다음 열 3(0 인덱스 = ) 값의 고정 값에서 이를 추출합니다..[0]
max
Num
.[2]
[관심 있는 독자를 위한 참고 사항: 0개의 행을 반환하도록 Column_1 기준을 변경하면 위의 코드는 max
내가 얻는 Column_3 값이 -Inf
]임을 알려줍니다.
의견을 읽으면 OP가 위 값이 포함된 전체 행을 반환하는 방법도 알고 싶어하는 것 같습니다. 다음 코드는 이 작업을 수행합니다.
~$ raku -e 'my @a = lines>>.words; @a.=grep(38 < *.[0] < 40); put max(@a, :by(*.[2].Num));' file
38.250 0.0000 -0.088557
마지막으로 독자는 여기에서 얻은 Column_3 값이 게시된 다른 답변과 다르다는 것을 알 수 있습니다. 이는 Column_1 값에 대한 요청인 경우 사용된 Raku 코드가 말한 대로 정확하게 OP를 가져오기 때문입니다.~ 사이38과 40(즉, 38보다 크고 40보다 작습니다). Column_3 값을 제공하는 대신 grep
위의 명령문을 자유롭게 변경하여 사용할 수 있습니다 (다른 답변과 동일).<=
<
-0.060678
입력 예:
37.500 0.0000 0.005605
37.750 0.0000 -0.027858
38.000 0.0000 -0.060678
38.250 0.0000 -0.088557
38.500 0.0000 -0.109210
38.750 0.0000 -0.122482
39.000 0.0000 -0.129770
39.250 0.0000 -0.133190
39.500 0.0000 -0.134538
39.750 0.0000 -0.134015
40.000 0.0000 -0.129660
40.250 0.0000 -0.117858
40.500 0.0000 -0.094709
40.750 0.0000 -0.057622
41.000 0.0000 -0.006853