해당 줄부터 계속 검색하려면 AWK FNR을 Bash 변수로 저장하세요.

해당 줄부터 계속 검색하려면 AWK FNR을 Bash 변수로 저장하세요.

정렬된 파일에서 실행하려고 합니다. 이전 9개 문자와 비교하여 주어진 값보다 작거나 같은 마지막 줄을 반환합니다.

이는 여러 번 실행되고 VALUE각 실행마다 할당되며 이전 솔루션을 찾은 후 해당 줄에서 계속 검색해야 합니다. 현재 줄 번호를 제공한다는 것을 알고 있지만 FNR조작하기 위해 BASH 변수로 저장할 수는 없습니다.

file모습은 다음과 같습니다.

093051721DABCD
093052654EEFGH
093053087TIJKL

$ VALUE=093052054;
$ cat file | awk '{if((substr($0,0,9) <= $VALUE)){print $0} else exit}' | tail -1
093051721DABCD

다른 방법이 있나요?

답변1

VALUE=083551726
awk -v CMPVALUE="$VALUE" '{linevalue=substr($0,0,9)+0; CMPVALUE=CMPVALUE+0;
  if(linevalue > CMPVALUE) exit; lineno=FNR};
  END {if (lineno>0) print lineno " " $0;
  else print "0 ";}' file
0 

VALUE=083551726555
awk -v CMPVALUE="$VALUE" '{linevalue=substr($0,0,9)+0; CMPVALUE=CMPVALUE+0;
  if(linevalue > CMPVALUE) exit; lineno=FNR};
  END {if (lineno>0) print lineno " " $0;
  else print "0 ";}' file
3 093053087TIJKL

답변2

bash버전을 고려해보세요:

#! /bin/bash
exec 3<test.txt
COUNT=0
while read VALUE
do
    if [[ -z $LAST_VAL ]]
    then
        IN_VAL="$LAST_VAL"
    else
        LINE="$(head <&3 -1)"
        IN_VAL="$(cut -c1-9 <<<'$LINE')"
        let COUNT=$COUNT+1
    fi

    while [[ $IN_VAL < $VALUE ]]
    do
        LINE="$(head <&3 -1)"
        IN_VAL="$(cut -c1-9 <<<'$LINE')"
        let COUNT=$COUNT+1
        LAST_VAL="$IN_VAL"
        [[ -z $IN_VAL ]] && break
    done
    echo $((COUNT - 1)) $LINE
    [[ -z $IN_VAL ]] && break
done

headgrep(및 와 같은 일부 다른 도구 --max-count)와는 달리 awk마지막 문자를 읽은 후 스트림을 유지하므로 나중에 동일한 스트림으로 계속 검색할 수 있습니다. 문제는 읽은 값이 일치하지 않아서 다음 iteration을 위해 저장해야 하는 경우입니다(참고자료에서 했던 것처럼 LAST_VAL). COUNTsum 값은 LINE마지막으로 일치하는 줄 번호와 줄이어야 합니다. 이렇게 하면 파일을 한 번만 읽어도 모든 작업을 완료할 수 있습니다.

관련 정보