Bash: maneira nativa de se livrar da cotação em torno de cada membro da matriz

4

Eu li uma matriz de outro script. Essa matriz precisa colocar " " em todos os membros da matriz, pois alguns membros estão vazios.

in_file=./data
vector=($(./readdata.sh 0 $in_file))
for index in ${!vector[@]}
do
    echo ${vector[index]}
done

O problema é que tenho cotações em torno de cada linha de saída e quero me livrar delas.

"red"
"blue"
"green"
""
"white"
"black"

deve mudar para:

red
blue
green

white
black

Eu procuro um método que não use awk , tr , sed ou qualquer outra maneira baseada em pipeline. Eu só quero resolver usando formas nativas, como o uso de parênteses, pontuações diferentes, ....

    
por ar2015 02.04.2015 / 08:22

4 respostas

4

Isso pode funcionar:

in_file=./data
vector=($(./readdata.sh 0 $in_file))
for index in ${!vector[@]}
do
    echo ${vector[index]//\"/}
done

Ref: link

    
por 02.04.2015 / 08:28
3

Você tornará seu programa mais simples e mais robusto se readdata.sh produzir dados delimitados por nova linha, sem citações extras.

No seu programa atual, a saída de readdata.sh é dividida em espaço em branco (por exemplo, "a b" resulta em dois elementos de matriz "a e b" ) e cada palavra resultante é interpretada como um padrão curinga (por exemplo "a * b" resulta em "a , depois os nomes dos arquivos no diretório atual e, finalmente, b" ). Veja Por que meu script de shell engasgar com espaço em branco ou outros caracteres especiais? para mais detalhes.

O Bash fornece uma maneira muito simples de ler dados delimitados por novas linhas: o mapfile embutido. Como o bash executa o lado direito de um pipeline em um subshell, você não pode simplesmente escrever ./readdata.sh 0 "$in_file" | mapfile -t vector , você tem que colocar o uso da variável em um bloco de comando, ou você pode usar a substituição do processo:

in_file=./data
mapfile -t vector < <(./readdata.sh 0 "$in_file")
for index in "${!vector[@]}"
do
  echo "$index: ${vector[index]}"
done

Se você não estiver usando os índices, apenas os elementos, uma maneira mais simples de iterar sobre a matriz é

for element in "${vector[@]}"
do
  echo "$element"
done
    
por 03.04.2015 / 01:57
2

Como você prefere um liner,

vector=("${vector[@]//\"/}")

Lembre-se de que as substituições de texto podem funcionar para o array como um todo.

    
por 03.04.2015 / 17:48
1

Se você quiser evitar uma solução de pesquisa e substituição "hacky", usar eval parece fazer o trabalho:

vector=( $(eval echo ${vector[@]}) )

Isso faz com que o shell os interprete como argumentos citados para echo , o que remove as aspas. Claro, a linha acima como está ainda tem problemas com espaço em branco, mas o ponto chave aqui é a idéia de usar eval .

    
por 23.01.2017 / 17:29