awk ward problem

4

Estou tentando usar o awk para extrair alguns campos diferentes de uma string.

Exemplo:

selected="a2.flac|a3.flac|a4.flac"
first_file=$(echo "$selected" | awk -F'|' '{print $1}')

O código acima retorna a2.flac, que é o que eu esperava. Mas agora, eu quero iterar sobre uma variável e puxar cada arquivo um de cada vez. Então eu tentei isso:

i=1
first_file=$(echo "$selected" | awk -F'|' '{print $i}')

Eu pensei que isso iria retirar o primeiro arquivo ... mas nada retorna. então eu tentei isso em seguida:

i=1
first_file=$(echo "$selected" | awk -F'|' '{print \$i}')

Isso também não funcionou. Eu também tentei este método:

i=1
first_file=$(echo "$selected" | awk -F'|' n=$i '{print $n}')

E também tentei isso:

i=1
first_file=$(echo "$selected" | awk -v -F'|' n=$i '{print $n}')

Nada que eu tentei parece funcionar. Estou perplexo com o que vai funcionar.

    
por daniel 09.10.2015 / 15:44

3 respostas

3

você quase faz isso

i=1
first_file=$(echo "$selected" | awk -v n="$i" -F'|'  '{print $n}')
    A variável
  • é definida usando -v name = value
por 09.10.2015 / 15:52
4

Seu $i é uma variável do shell, awk não tem acesso a ele, portanto, $i é avaliado como vazio. Você pode i) usar double qupted para o script awk para que o shell expanda variáveis dentro dele antes de passá-lo para awk para execução ou ii) passe-o para awk como uma variável awk :

  • Use aspas duplas. Note que como o shell agora está expandindo variáveis, você precisará escapar do primeiro $ para que ele seja passado para awk e não seja interpretado pelo shell:

    $ i=1
    $ first_file=$(echo "$selected" | awk -F'|' "{print \$$n}")
    $ echo "$first_file"
    a2.flac
    
  • Passe a variável para awk . Você tinha a sintaxe quase correta:

    $ first_file=$(echo "$selected" | awk -F'|' -vi="$i" '{print $i}')
    $ echo "$first_file"
    a2.flac
    
por 09.10.2015 / 15:53
2

O valor de $ i é definido pelo shell, para poder fazer isso, a string deve ser entre aspas duplas ou sem aspas. Assim, sua linha:

i=1; first_file=$(echo "$selected" | awk -F'|' '{print $i}')     # original
i=1; first_file=$(echo "$selected" | awk -F'|' '{print $'$i'}')  # un-quoted
i=1; first_file=$(echo "$selected" | awk -F'|' '{print $'"$i"'}') # double-quoted
i=1; first_file=$(echo "$selected" | awk -F'|' "{print \$$i}")  # full double-quoted

Claro, você poderia, e é a maneira mais correta de fazer isso, dizer ao awk qual é o valor do var, e usá-lo (eu usei jj para fazer a diferença em nomes de variáveis explícitas):

i=1; first_file=$(echo "$selected" | awk -F'|' -v jj="$i" '{print $jj}') 

Talvez uma maneira mais idiomática seja (sem sub-shell por causa do pipe "|"):

i=1; first_file="$( <<<"$selected" awk -F\| '{print $'$i'}')"
    
por 10.10.2015 / 04:58

Tags