루프 변수를 사용하여 각 루프에서 단어 가져오기

루프 변수를 사용하여 각 루프에서 단어 가져오기

나는 각 루프에서 단어를 얻으려고 노력하고 있습니다. 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인수로 스크립트에 전달하는 것입니다.-vvariable

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

이 변수는 따옴표 없이 사용되므로 안전하지 않을 수 있습니다.

관련 정보