나는 각 루프에서 단어를 얻으려고 노력하고 있습니다. i
에 삽입하는 방법을 모르겠습니다 print $2
.
while [ $i -lt 4 ]
do
A=$(awk -F_ '{print $2}' <<< 'one_two_test_three')
echo $A
done
분명히 이것은 다음과 같이 출력됩니다.
two
two
two
two
내가 원하는 것은:
one
two
test
three
나는 시도했다:
A=$(awk -F_ '{print $($i)}' <<< 'one_two_test_three')
쓸모 없는.
답변1
올바른 방법은 ( ) 옵션을 통해 bash/shell
변수를 awk
인수로 스크립트에 전달하는 것입니다.-v
variable
i=1;
while [ $i -lt 5 ]; do
A=$(awk -v i="$i" -F_ '{ print $i }' <<< 'one_two_test_three')
echo $A
((i++))
done
산출:
one
two
test
three
답변2
데이터를 구문 분석하는 데 쉘 루프가 필요하지 않습니다.
$ awk -F '_' '{ for (i=1; i<=NF; ++i) print $i }' <<<'one_two_test_three'
one
two
test
three
스크립트는 입력을 _
구분된 목록으로 구문 분석하고 각 필드를 인쇄합니다.
더 짧게:
$ awk -F '_' 'BEGIN { OFS="\n" } { $1=$1 } 1' <<< 'one_two_test_three'
one
two
test
three
이는 출력 필드 구분 기호를 개행 문자로 설정한 다음 레코드를 인쇄하기 전에 전체 레코드를 강제로 재구성(새 구분 기호 삽입)하도록 합니다.
더 짧게:
$ tr '_' '\n' <<<'one_two_test_three'
one
two
test
three
데이터를 통한 루프:
tr '_' '\n' <<<'one_two_test_three' |
while read -r word; do
printf 'Got "%s"\n' "$word"
done
이렇게 하면 데이터를 여러 번 구문 분석하는 데 사용되는 유틸리티를 호출하지 않습니다.
답변3
값에 개행 문자가 없다고 가정하면 다음과 같습니다. 코드가 작동하려면 최소한의 변경이 필요합니다. 를 #!/bin/bash
사용하고 있으므로 shebang은 (ksh 또는 zsh) 여야 합니다 <<<
.
i=1
while [ "$i" -le 4 ]
do
A=$(awk -v var="$i" -F_ '{print $var}' <<< 'one_two_test_three')
echo "$A"
i=$((i+1))
done
그러나 문자열은 셸에서 나오므로 다음과 같이 단순화할 수 있습니다.
IFS=_ read v1 v2 v3 v4 <<<'one_two_test_three'
printf '%s\n' "$v1" "$v2" "$v3" "$v4"
그리고 값 배열(가변 개수의 값)을 사용합니다.
#!/bin/bash
IFS=_ read -a v <<<'one_two_test_three'
printf '%s\n' "${v[@]}"
더 간단한 셸을 사용해야 하는 경우:
#!/bin/sh
IFS=_ read v1 v2 v3 v4 <<-_expandvar_
one_two_test_three
_expandvar_
printf '%s\n' "$v1" "$v2" "$v3" "$v4"
물론 변수를 설정할 필요가 없다면 스크립트에서 IFS 값을 설정하는데 문제가 없습니다.
#/bin/sh
a='one_two_test_three'
IFS=_
set -f
printf '%s\n' $a
이 변수는 따옴표 없이 사용되므로 안전하지 않을 수 있습니다.