Alterando matrizes em linhas únicas de dados

4

Eu tenho várias matrizes em um arquivo .txt e preciso que cada matriz esteja em uma única linha. Por exemplo,
matrices.txt:

1 2 3 4
2 3 4 5
3 4 5 6

3 4 5 6
2 3 2 5
2 3 4 5
2 3 5 6
2 3 4 5
...

O que eu gostaria é de modified_matrices.txt :

1 2 3 4 2 3 4 5 3 4 5 6
3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 5
...

Existem cerca de 1000 matrizes no arquivo e elas não são todas inteiras (0,88888888889888).

    
por hopeless_newbee 25.08.2015 / 19:17

6 respostas

4

Possível awk solução poderia ser:

awk 'BEGIN { RS = ""; } { $1 = $1; } 1' matrices.txt > modified_matrices.txt
    
por 25.08.2015 / 19:34
2

No Vi / Vim você pode executar simplesmente:

:%j

para unir todas as linhas, ou:

:%v/^$/-1j

para unir todas as matrizes separadas por uma nova linha ( Unir linhas entre um determinado padrão de texto no Vim ).

Se você precisar que isso seja feito na linha de comando, tente:

ex -s +%j +"wq modified_matrices.txt" matrices.txt

para participar de todas as linhas ou:

ex -s +'%v/^$/-1j' +'wq! modified_matrices.txt' matrices.txt

para juntar todas as matrizes separadas por nova linha:

    
por 25.08.2015 / 20:05
1

Você pode fazer isso com um pequeno script bash:

$ cat data
1 2 3 4
2 3 4 5
3 4 5 6

3 4 5 6
2 3 2 5
2 3 4 5
2 3 5 6
2 3 4 5

$ cat foo.sh
#!/bin/bash

while read line; do
    if [[ "${line}" = "" ]]; then
        echo ""
    else
        echo -n "${line} "
    fi
done
echo ""

$ bash foo.sh < data
1 2 3 4 2 3 4 5 3 4 5 6
3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 5
    
por 25.08.2015 / 19:31
1
  • com tr e sed :

Substitua todas as novas linhas por hashes (escolha qualquer outro símbolo que não esteja presente em suas matrizes se você tiver hashes), então os hashes duplos devem ser novas linhas e os únicos apenas espaços: (GNU sed )

 tr '\n' '#'  <file  | sed 's/##/\n/g;s/#/ /g'

POSIX sed

 tr '\n' '#'  <file  | sed 's/##/\
 /g;s/#/ /g'
  • Em relação ao tamanho do arquivo:

Talvez você também queira dividir o arquivo em blocos de matriz - arquivo separado para cada um e reuni-los. Note que isso é um monte de operações de leitura / gravação e só deve ser considerado se as outras soluções forem além de suas capacidades de RAM.

csplit -b%04d -f file file '/^$/' '{*}'

Ou seja. dividir file em arquivos denominados fileXXXX com XXXX inteiro contínuo, como marcador de separação, usar linhas vazias '/^$/' ; faça para todas as ocasiões '{*}' . Agora reúna os arquivos peça por peça com um script de shell:

for f in file???? ; do 
  sed '/^$/d' $f | tr '\n' ' ' >> newmatrices
done

Ou seja. remova as linhas vazias que usamos como marcadores de divisão antes, depois tr anslate newlines para espaços e acrescente cada linha ao arquivo newmatrices output.

É claro que tanto a separação quanto a reunificação podem ser colocadas em um único script.

Observe que não sei se csplit possui padrões diferentes em sistemas diferentes.

    
por 25.08.2015 / 19:50
1

sed apenas:

sed '/^$/!{H;$!d;};x;s/.//;y/\n/ /' infile > outfile

Isso acumula linhas não vazias no espaço de armazenamento e as exclui, se não a última linha, caso contrário, troca buffers, remove a nova linha principal e converte todas as novas linhas para espaços.
Com blocos separados por um número arbitrário de linhas vazias, para colapsá-los em um único:

sed '/^$/!{         # if line isn't empty
H                   # append to hold space
$!d                 # if it's not the last line, delete it
b end               # branch to label end (this happens only if on the last line)
}
//b end             # if line is empty, branch to label end
: end               # label end
x                   # exchange pattern space w. hold space
//d                 # if pattern space is an empty line, delete it; else
s/\n//              # remove the leading \newline
s/\n/ /g            # replace all remaining \newline chars with spaces
' infile > outfile

ou, como um one-liner:

sed '/^$/!{H;$!d;$b end;};//b end;: end;x;//d;s/\n//;s/\n/ /g' infile > outfile
    
por 11.09.2016 / 13:57
0

Outra one-liner:

$ sed -rz 's/\n([^\n])/ /g;s/\n /\n/g' matrices.txt
1 2 3 4 2 3 4 5 3 4 5 6
3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 5
$ 

Como o -z faz com que o sed leia todo o arquivo como uma linha, isso será menos adequado para arquivos de entrada grandes.

    
por 26.08.2015 / 02:01