Possível awk
solução poderia ser:
awk 'BEGIN { RS = ""; } { $1 = $1; } 1' matrices.txt > modified_matrices.txt
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).
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:
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
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'
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.
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
Tags text-processing sed