armazena a saída do comando em uma matriz e imprime um por um

1

Este é o meu comando:

cat httpd.conf | grep ^LogFormat | awk -F\" '{print $(NF)}'

Resultado disso:

commonsess
common

ou pode ser qualquer número de valores, eu preciso armazenar esses valores em uma matriz e imprimir um por um ... usando seu número de índice.

    
por user79658 11.08.2014 / 14:04

3 respostas

2

Usar matrizes ou loops em shells geralmente é sinal de prática de codificação incorreta. Um shell é uma ferramenta para executar outros comandos. awk é o comando típico para executar tarefas complicadas com campos em registros de texto. Você deseja chamar awk uma vez para sua tarefa, não um loop no qual você executará centenas de comandos.

Se você quiser imprimir um índice e o último nome de campo para as linhas que começam com ^LogFormat , é:

awk '/^LogFormat/{print n++, $NF}' httpd.conf

Não há necessidade de cat (que é para concatenar), nem grep ( awk é um superconjunto de grep ) ou uma matriz shell ou um loop de shell.

    
por 11.08.2014 / 14:23
2

Para começar, usar cat, grep and awk geralmente está errado. Você agora tem

cat /etc/httpd/conf/httpd.conf | grep ^LogLevel | awk -F\" '{print $(NF)}'

Para ler as linhas em uma matriz, você pode usar read

while read -rd '' -a array
 do array+=("$REPLY")
 done < <(awk -F\" '/^LogFormat/{ print $(NF)}' httpd.conf)
printf '%s\n' "${array[0]}"
    
por 11.08.2014 / 14:25
0

Em resumo ,
você pode usar:

a=( $(awk '/^LogFormat/{print $(NF)}' httpd.conf) )

para obter as palavras do httpd.conf na variável de array a .

Você pode acessar os elementos pelo índice agora:

$ echo ${a[2]}
common

Explicado e ilustrado

Como atribuir matrizes:

$ a=( e1 e2 e3 )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""  
count: 3, a[2]: "e2"

Alguma configuração do shell :

Isto não é necessário para este exemplo, onde sabemos que temos apenas palavras como valores, mas, em geral, é muito importante.
Precisamos da opção -f para evitar globbing se os valores contiverem * ou ? .
Além disso, devemos definir o IFS do separador de campo interno de acordo com nossos dados, se não forem palavras simples (e salvá-lo e restaurá-lo).

$ # set -f
$ # IFS=$'\n'

Nosso teste entrada :

$ in=httpd.conf
$ grep '^LogFormat' "$in"  | awk -F\" '{print $(NF)}'
 combined
 common
 referer
 agent

Com seu comando original :

$ a=( $(cat "$in" | grep '^LogFormat' | awk -F\" '{print $(NF)}') )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""
count: 4, a[2]: " common"

Com a versão mais curta de @ StéphaneChazelas:

$ a=( $(awk '/^LogFormat/{print $(NF)}' $in) )
$ echo "count: ${#a}, a[2]: \"${a[2]}\""  
count: 4, a[2]: "common"
    
por 11.08.2014 / 15:34

Tags