bash: Use colunas separadas em um array

2

É possível colocar colunas separadas em matrizes, não como uma linha, mas como uma coluna. Eu preciso acessar as linhas seqüencialmente. Eu tenho um arquivo, mas neste exemplo, os arquivos são divididos em colunas e usados separadamente.

arquivo de exemplo:

column1  column2  column3
  444      999      000                 
  555      888      xxx 
  666      777      xxx

arquivo de saída:

output is 444  bla  999  bla  000                   
output is 555  bla  888  bla  xxx   
output is 666  bla  777  bla  xxx 

O que eu tentei é o seguinte:

readarray -t column <firstcolumn.txt
for i in "${column1[@]}";  do
    readarray -t  column2 <secondcolumn.txt
    for j in "${column2[@]}"; do
        readarray -t column3 <thirdcolumn.txt
        for k in "${column3[@]}";  do
            echo "output is $i bla $j bla $k"
        done
    done
 done
    
por Pheeb 27.05.2014 / 15:56

3 respostas

1

Este é um script simples que deve mostrar o uso de readarray . Eu continuo mais parecido com o que você postou.

#!/bin/bash 

awk '{ print $1 }' data.txt  >  file_column1.txt
awk '{ print $2 }' data.txt  >  file_column2.txt
awk '{ print $3 }' data.txt  >  file_column3.txt
# NLines=' wc -l data.txt | awk '{print $1}''

readarray -t column1 < file_column1.txt
readarray -t column2 < file_column2.txt
readarray -t column3 < file_column3.txt

i=0;
for item in "${column1[@]}"; do
   echo  output is ${column1[$i]} bla ${column2[$i]}  bla ${column3[$i]}; 
   let "i=i+1" 
done

# rm -f file_column1.txt file_column2.txt file_column3.txt

Comentários :

  • Com awk , você pode imprimir a coluna desejada ( $1 para o primeiro, $2 para o segundo e assim por diante). Você cria um arquivo diferente para cada coluna.
  • Se não comentada, a linha #Nlines=wc -l | awk '{print $1}' poderia ser usada para manter a contagem do número de linhas para o vetor que será criado depois com readarray e para fazer o loop de uma maneira diferente ...
  • Com readarray você leu o arquivo único e inseriu um vetor 1D.
  • O loop for é feito para cada componente da coluna do vetor 1D1. Deve ser feito tomando cada vetor porque no seu exemplo eles têm o mesmo tamanho. Isso deve ser feito usando Nlines .
  • Na variável não usada item dentro do loop, há sempre o mesmo valor de column1 [i]
  • Você acessa diretamente o componente que você deseja da matriz (o primeiro índice é 0 e o último é Nlines-1 )
  • Você aumenta o valor de i em cada iteração do loop for .
  • Se necessário, remova o comentário para apagar os arquivos temporários criados no script.

A saída é

 output is 444 bla 999  bla 000 
 output is 555 bla 888  bla xxx 
 output is 666 bla 777  bla xxx 

Último comentário
Se você aninhar 3 loop (um dentro do outro) você obterá cada permutação: não 3 mas 3 * 3 * 3 = 27 linhas

 0 0 0  
 0 0 1   
 0 0 2   
 0 1 0  
 ...
    
por 27.05.2014 / 19:16
0

Por que você não carrega os arrays separadamente da operação em que você os imprime?

readarray -t column1 <column1.txt
readarray -t column2 <column2.txt
readarray -t column3 <column3.txt

for (( i=0; i<${#column1[@]}; i++ )); do
    echo -e "output is ${column1[$i]} bla ${column2[$i]} bla ${column3[$i]}"
done
    
por 27.05.2014 / 18:48
0

Não sei se entendi sua pergunta corretamente, você parece estar pedindo uma coisa, mas sua saída mostra outra. Para obter o resultado desejado, tudo que você precisa é

while read col1 col2 col3; do
    echo "output is $col1  bla  $col2  bla  $col3"
done < file

Ou, para pular o cabeçalho:

tail -n +2 file | while read col1 col2 col3; do     
    echo "output is $col1  bla  $col2  bla  $col3"; 
done 

Se você realmente precisar deles em uma matriz, tente algo como

i=0; 
while read col1 col2 col3; do 
    col1s[$i]=$col1; 
    col2s[$i]=$col2; 
    col3s[$i]=$col3; 
    let i++; 
done < <(tail -n +2 file); 
k=0;
for(( k=0; k<i; k++ )); do 
    echo "output is ${col1s[$k]} blah ${col2s[$k]} blah ${col3s[$k]}"; 
done
    
por 27.05.2014 / 21:33