Como posso armazenar cada linha inteira separada em um arquivo de texto em uma matriz?

0

Eu tenho um arquivo chamado "threewords". Ele contém as informações:

\#gray speedy bee

gr-A | sp-E-d-E | b-E

\#gray greedy pea

gr-A | gr-E-d-E | p-E

Quando eu executo o comando:

cat threewords | grep ^# | cut -c2-

O comando puxa as duas linhas começando com #. Em seguida, remove o # e retorna isso como saída:

gray speedy bee

gray greedy pea

Quando executo meu comando:

array=($(cat threewords | grep ^# | cut -c2-))

Ele cria a matriz, mas separa todas as palavras em posições separadas da matriz como esta:

array[0] = gray,
array[1] = speedy,
array[2] = bee,
array[3] = gray,
array[4] = greedy,
array[5] = pea

Eu posso descobrir o código para colocar a saída de cada linha em uma matriz da seguinte forma:

array[0] = gray speedy bee, 
array[1] = gray greedy pea
    
por Ben 13.12.2014 / 23:52

2 respostas

2

A divisão é feita com IFS como o delimitador (que contém um espaço, nova linha e tab por padrão). Defina o IFS apenas para a nova linha:

$ IFS=$'\n' a=($(printf "1 2\n2 3\n"))
$ echo ${a[0]}
1 2
$ echo ${a[1]}
2 3

Isso alterará IFS para o shell, então é melhor salvá-lo antes e restaurá-lo:

OLD_IFS="$IFS"
IFS=$'\n' array=($(grep '^#' threewords | cut -c2-))
IFS="$OLD_IFS"

E não há absolutamente nenhum motivo para fazer:

cat threewords | grep '^#'

grep é perfeitamente capaz de ler arquivos:

grep '^#' threewords

Como Stephane observa que, ao submeter a saída de um comando a uma expansão adicional do shell, deve-se desabilitar o globbing usando set -f :

$ help set 
...
      -f  Disable file name generation (globbing).

Caso contrário:

$ cd /; a=( $(printf "*\n") )
$ echo ${a[@]}
bin boot cdrom dev etc home ...
    
por 13.12.2014 / 23:59
2

Se você tiver bash 4

mapfile -t array < <(grep ^# threewords | cut -c2-)

preencherá array , uma linha por elemento

printf "%s\n" "${array[@]}"
gray speedy bee
gray greedy pea
    
por 14.12.2014 / 01:44

Tags