입력의 N 열마다 출력

입력의 N 열마다 출력

시작 열, 증분 값 및 파일 이름을 런타임 매개변수로 전달하여 파일의 모든 N 열을 인쇄하는 스크립트를 작성하려고 합니다. 아래는 내 스크립트입니다.

file=$1
st=$2
inc=$3

echo $file
echo $st
echo $inc

awk '{for (i = $st; i <= NF; i += $inc) printf ("%s%c", $i, i + $inc <= NF ? " " : "\n");}' $file

결과를 얻을 수 없습니다. 누구든지 나를 도와줄 수 있나요? 내 입력은 다음과 같을 수 있습니다script.sh file_name 1 4

미리 감사드립니다. :-)

답변1

쉘 변수 는 자동으로 변수가 되지 않습니다 awk( 에서 변수는 th 필드 가 아닌 awk으로 표시됩니다 ). 쉘 변수를 에 전달하려는 경우 쉬운 방법은 환경을 사용하는 것입니다.var$varvarawk

#! /bin/sh -
file=$1
ST=$2
INC=$3

export ST INC
awk '
  {
    sep = ""
    for (i = ENVIRON["ST"]; i <= NF; i += ENVIRON["INC"]) {
      printf "%c%s", sep, $i
      sep = OFS
    }
    printf "\n"
  }' < "$file"

쉘 변수를 인용하고 임의의 파일 이름을 인수로 사용하지 마십시오(그 중 일부는 a 또는 특별히 호출된 파일 이름 awk으로 처리하므로 ).=-

변수를 전달하는 또 다른 방법 은 awkawk 스크립트 뒤에 -v awkvar="$shellvar"또는 매개변수를 사용하는 것입니다. 그러나 이스케이프 시퀀스가 ​​확장되고(예: 개행 문자가 됨) GNU 4.2 이상 awkvar="$shellvar"에서는 임의의 문자열과 함께 사용할 수 없습니다 .\\\\nawk로 시작 @/하고 끝나는 값은 /특별하게 취급됩니다.POSIX 모드를 제외하고.

awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc)...}' < "$file"

또는

awk  '{for (i = st; i <= NF; i += inc)...}' st="$st" inc="$inc" < "$file"

이 변수에는 숫자만 포함되므로(백슬래시가 없음) 여기서는 괜찮습니다.

무엇을 하든 하지 마세요:

awk 'for (i = '"$st"'; i <= NF; i += '"$inc"')...'

언급 할 필요없는

awk 'for (i = '$st'; i <= NF; i += '$inc')...'

즉, 쉘이 에 전달된 코드의 값과 변수를 확장하도록 하십시오 $st. 이렇게 하면 명령 주입 취약점(예: 다음과 같은 값)이 발생할 수 있습니다.$incawkstsystem("reboot")

답변2

귀하의 스크립트를 수정했으며 이제 작동합니다. 두 가지 오류가 있습니다. (a) 쉘 변수를 awk에 수동으로 전달해야 하며(이것은 구문을 사용하여 수행됨) (b) 변수를 나타내는 데 이를 -v awk_var="$shell_var"사용해서는 안 됩니다. 기호는 필드 위치에만 사용됩니다.$$

file=$1
st=$2
inc=$3

echo $file
echo $st
echo $inc

awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc) printf ("%s%c", $i, i + inc <= NF ? " " : "\n");}' $file

관련 정보