for 루프 내부의 awk 명령

for 루프 내부의 awk 명령

awk루프 내에서 명령을 사용해 보았지만 성공하지 못했습니다 for.

데이터를 가져오기 위해 잘라내는 데 사용할 일련의 문자열이 포함된 변수가 있습니다 awk.

어떻게 해야 하는지는 알지만, 제가 정말 원하는 것은 데이터를 계속해서 잘라내는 것입니다.

그래서 저는 이 변수를 가지고 있습니다:

var="data1,data2,data3"

나는 지금 여기 있다:

for ((i=1; i<=3; i++))
do
    echo $(awk -F, '{print $1}' <<< $var)
done

$1루프로 교체하려고 시도했지만 $i성공하지 못했습니다.

답변1

큰따옴표를 사용하여 awk 스크립트에 쉘 변수를 삽입하면 원하는 것을 얻을 수 있습니다. 여전히 리터럴을 유지하고 싶다면 $백슬래시를 사용하여 이스케이프 처리하면 됩니다.

echo $(awk -F, "{print \$$i}" <<<$var)

이는 각 반복마다 , 및 를 확장하므로 $iawk는 , 및 을 보게 되며, 이로 인해 모든 필드가 확장됩니다.123$1$2$3

또 다른 가능성은 다음 플래그를 사용하여 쉘 변수를 awk 변수로 주입하는 것입니다 -v.

echo $(awk -F, -v i="$i" '{print $i}' <<<$var)

awk 변수 할당동일한 이름을 가진 쉘 변수의 내용에. awk의 변수는 a를 사용하지 않으며 $필드용이므로 $i참조하기에 충분합니다.- 첫 번째 필드인 경우awk의 변수입니다.

awk 변수에 값을 할당하는 것은 -v일반적으로 더 안전한 접근 방식입니다. 특히 임의의 문자 시퀀스를 포함할 수 있는 경우 콘텐츠가 의도와는 반대로 awk 코드로 실행될 위험이 적습니다. 그러나 귀하의 경우 변수는 단일 정수를 보유하므로 걱정하지 마십시오.

for또 다른 옵션은 awk 자체 내에서 루프를 사용하는 것입니다. 이를 수행하는 방법에 대한 자세한 내용은 awk 문서를 참조하거나 이 사이트를 검색하십시오.

답변2

이 경우에는 사용이 너무 많은 것 같습니다. 따라서 awkwhile 루프를 사용하는 것은 어떻습니까?tr

tr , '\n' <<<"$var" | while read; do
  echo $REPLY
done

산출:

data1
data2
data3

답변3

#!/bin/sh

var='data1,data2,data3'

unset data
while [ "$var" != "$data" ]; do
    data=${var%%,*}    # delete first comma and the bit after it
    var=${var#*,}      # delete bit up to first comma (and the comma)

    printf 'data = "%s"\n' "$data"
done

여기서는 변수 대체를 사용하여 변수 값에서 각각의 연속적인 쉼표로 구분된 데이터 필드를 가져옵니다 var. data루프의 첫 번째 할당은 $var첫 번째 쉼표 뒤의 모든 내용을 삭제합니다. 그런 다음 var첫 번째 쉼표 앞의 첫 번째 숫자가 제거되도록 변수를 수정합니다 .

"$var" = "$data"이는 문자열에 대해 어떤 작업도 수행할 수 없음을 의미할 때까지 계속됩니다 .

이 접근 방식을 사용하면 새 줄이 포함된 쉼표로 구분된 데이터 문자열을 처리할 수 있습니다.

var='line1
line2,data2,last bit
goes here'

위의 값을 사용하면 var위 스크립트가 출력됩니다.

data = "line1
line2"
data = "data2"
data = "last bit
goes here"

삽입된 개행 문자는 신경 쓰지 않습니다.희귀한루프에서 호출해야 합니다 awk.

awk문자열을 쉼표로 구분된 필드 집합으로 읽는 것이 매우 좋으며 해당 필드를 반복할 수 있습니다 .

printf '%s\n' "$var" |
awk -F ',' '{ for (i=1; i<=NF; i++) print $i }'

를 사용하면 var='data1,data2,data3'인쇄됩니다.

data1
data2
data3

또 다른 셸 솔루션은 IFS변수를 활용하여 $var값을 비트로 분할하는 동시에 set -f파일 이름 확장도 비활성화합니다.

set -f
oldIFS=$IFS; IFS=','

set -- $var

IFS=$oldIFS; unset oldIFS
set +f

for data do
    printf 'data = "%s"\n' "$data"
done

답변4

j(변수로) 및 $j(필드 인덱스로) 다음을 허용합니다 .

for i in 1 2 3; do echo "$var" | awk -v j=$i -F , '{print $j}'; done

$i예제에서는 둘 다 접두사로 참조 awk되기 때문에 어느 것을 사용할지(셸 또는 자체 변수 - 우선순위) "혼란스럽습니다".$

노트

"이식 가능한" 스크립팅 표준인 셸은 다음을 지원하지 않습니다.

(( i=1; i<=3; i++; ))그리고 <<< $var빌드

또한 루프 seq내에서 명령을 사용하여 for숫자 시퀀스 생성을 더 효과적으로 제어할 수도 있습니다(사용 가능한 경우).

관련 정보