AWK: 쉘 변수를 awk에 전달

AWK: 쉘 변수를 awk에 전달

나는 a를 통과하려고 노력하고 있습니다변하기 쉬운쉘 스크립트에서 테이블의 패턴 인식 하위 집합까지의 인수 수입니다. 지금까지의 시도는 다음과 같습니다.

파일 'infile':

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

파일 subset.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자 문자열인 경우 foo\barawk 변수는 가 백스페이스 문자(바이트 값 8)인 6 group자 문자열로 설정됩니다 .foo␈ar

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

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

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

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

#!/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"

보다스테판 차젤라스의 답변입력 파일을 여러 번 처리할 필요가 없는 awk를 사용하는 고급 방법입니다.

관련 정보