Obter palavra em cada loop usando a variável de loop

0

Estou tentando obter a palavra em cada loop. Não consigo descobrir como inserir i em print $2 .

while [ $i -lt 4 ] 
do
    A=$(awk -F_ '{print $2}' <<< 'one_two_test_three')
    echo $A
done

Isso produzirá, obviamente:

two
two
two
two

O que eu quero:

one
two
test
three

Eu tentei:

A=$(awk -F_ '{print $($i)}' <<< 'one_two_test_three')

não funcionou.

    
por GeneCode 25.05.2018 / 08:47

3 respostas

3

O caminho certo é passar a variável bash/shell para o script awk como um argumento através da opção -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

A saída:

one
two
test
three
    
por 25.05.2018 / 08:55
4

Não há necessidade de um loop de shell para analisar os dados:

$ awk -F '_' '{ for (i=1; i<=NF; ++i) print $i }' <<<'one_two_test_three'
one
two
test
three

O script analisa a entrada como uma lista _ -delimited e imprime cada campo.

Mais curto:

$ awk -F '_' 'BEGIN { OFS="\n" } { $1=$1 } 1' <<< 'one_two_test_three'
one
two
test
three

Isso define o separador de campo de saída como uma nova linha e, em seguida, força a reconfiguração de todo o registro (com o novo separador inserido) antes de imprimir o registro.

Mais curto:

$ tr '_' '\n' <<<'one_two_test_three'
one
two
test
three

Acessando os dados em um loop:

tr '_' '\n' <<<'one_two_test_three' |
while read -r word; do
    printf 'Got "%s"\n' "$word"
done

Dessa forma, você não chama o utilitário usado para analisar os dados mais de uma vez.

    
por 25.05.2018 / 09:15
2

Supondo que os valores não tenham novas linhas, então: Seu código com alterações mínimas para que ele funcione: O shebang deve ser #!/bin/bash (ksh ou zsh), pois você está usando <<< .

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

No entanto, como a string vem do shell, isso poderia ser simplificado para:

IFS=_ read v1 v2 v3 v4 <<<'one_two_test_three'
printf '%s\n' "$v1" "$v2" "$v3" "$v4"

E usando uma matriz de valores (número variável de valores):

#!/bin/bash
IFS=_ read -a v <<<'one_two_test_three'
printf '%s\n' "${v[@]}"

Se for necessário que um shell mais simples seja usado:

#!/bin/sh
IFS=_ read v1 v2 v3 v4  <<-_expandvar_
one_two_test_three
_expandvar_
printf '%s\n' "$v1" "$v2" "$v3" "$v4"

Naturalmente, se não houver necessidade de definir uma variável, nem é um problema definir o valor do IFS em um script:

#/bin/sh
a='one_two_test_three'
IFS=_
set -f
printf '%s\n' $a

Observe que a variável está sendo usada sem cotação, o que pode ser inseguro.

    
por 25.05.2018 / 10:04

Tags