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)
이는 각 반복마다 , 및 를 확장하므로 $i
awk는 , 및 을 보게 되며, 이로 인해 모든 필드가 확장됩니다.1
2
3
$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
이 경우에는 사용이 너무 많은 것 같습니다. 따라서 awk
while 루프를 사용하는 것은 어떻습니까?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
숫자 시퀀스 생성을 더 효과적으로 제어할 수도 있습니다(사용 가능한 경우).