AWK: 쉘 변수를 awk에 전달

AWK: 쉘 변수를 awk에 전달

합격하려고 해요바꾸다쉘 스크립트에서 테이블의 패턴 인식 하위 집합까지의 인수 수입니다. 지금까지 시도한 내용은 다음과 같습니다.

파일 "infile":

    ID,GROUP
    1,GROUP2    
    2,GROUP2    
    3,GROUP4    
    4,GROUP4    
    5,GROUP5    
    6,GROUP5    
    7,GROUP23   
    8,GROUP23   
    9,GROUP23   

파일 하위 집합.sh:

    #!/bin/sh
    rm -f outfile_$week

    week = $1
    shift

    for TOKEN in "$@"
    do

    echo "adding records for" $TOKEN

    awk -F "," -v group = $TOKEN '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile >> outfile_$week
    done

또한 group = "$TOKEN", "group = $TOKEN"을 시도한 다음 둘 다 작은따옴표로 시도했습니다. 나는 다음과 같이 제출합니다.

    sh subset.sh 061314 GROUP2 GROUP23

오류 메시지가 거의 표시되지 않습니다.

    Usage: awk [-F fs][-v Assignment][-f Progfile|Program][Assignment|File] ...

도움을 주시면 대단히 감사하겠습니다. 감사합니다!

편집: 나는 달리기를 시도했다

    awk -F "," -v group ="GROUP1" '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile

아무 소용이 없습니다... (위와 동일한 오류) 이런 일이 발생하는 이유를 아는 사람이 있습니까?

답변1

다음과 같이 작성해야 합니다.

-v group="$TOKEN"

대신 -v group = $TOKEN에서 구문 오류가 발생합니다 awk.

답변2

당신이 원하는 것 같아요 :

awk -F, '
  BEGIN {
    for (i = 1; i < ARGC; i++) group[ARGV[i]]
    ARGC=0
  }
  NR >= 2 && $2 in group' "$@" < infile

또는 인수를 두 번째 열과 일치하는 정규식으로 처리하려는 경우:

awk -F, '
  BEGIN {
    for (i = 1; i < ARGC; i++) group[ARGV[i]]
    ARGC=0
  }
  NR >= 2 {
    for (i in group) if ($2 ~ i) {print; next}
  }' "$@" < infile

답변3

직면하고 있는 즉각적인 문제는 등호 주변의 공백입니다. 이 옵션에 대한 인수는 -v할당이어야 합니다. awk는 인수 -v, 스크립트( =), 파일 이름( 값 TOKEN, 스크립트 및 파일 이름)을 확인합니다.

쉘 스크립트에서 비슷한 실수를 저질렀습니다. week = $1이어야 합니다 week="$1".

그런데,명령 대체에는 항상 큰따옴표를 사용하세요.. 예를 들어 TOKENis 인 경우 *현재 디렉터리의 파일 목록으로 대체됩니다.

awk -v "group=$TOKEN"

그러나 awk는 할당의 오른쪽을 awk 구문의 리터럴로 처리하기 때문에 group값을 로 설정하지 않습니다 . TOKEN예를 들어, 값이 TOKEN7자 string 이면 foo\barawk 변수는 group6자 string 으로 설정됩니다 foo␈ar. 여기서 백스페이스 문자는 (바이트 값 8)입니다.

변수를 awk 스크립트에 전달하는 간단한 방법은 변수를 환경으로 내보내고 배열을 통해 사용하는 것입니다 ENVIRON.

group또한 awk 스크립트의 어느 곳에서도 이 변수를 사용 하지 않습니다 . 정규식은 /group/5자 문자열을 포함하는 모든 문자열과 일치합니다 group. 필드가 값과 정확히 같은지 확인하려면 group(예를 들어 값이 이면 TOKEN포함 GROUP2된 필드가 GROUP24일치하지 않음) 같음 연산자를 사용합니다 ==.

  export TOKEN
  awk -F "," '{ if (FNR > 2 && $2 == ENVIRON["TOKEN"]){print $0} }' infile >> outfile_$week

전체 스크립트는 다음과 같습니다. awk의 조건부 작업 구문( print $0기본값이므로 여기에서는 작업이 생략됨)을 사용하고 매번 출력 파일을 열지 않도록 더욱 단순화되었습니다.

#!/bin/sh
week="$1"
shift
for TOKEN in "$@"
do
  echo "adding records for" $TOKEN
  awk -F "," 'FNR > 2 && $2 == ENVIRON["TOKEN"]' infile 
done >"outfile_$week"

바라보다Stefan Chazeras의 답변awk를 사용하는 고급 방법에서는 입력 파일을 여러 번 처리할 필요가 없습니다.

관련 정보