Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

1. Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

césar
cesarufmt

(usa Linux Mint)

Enviado em 26/09/2014 - 03:20h

Olá.

Meu objetivo é pegar um arquivo csv com 333 mil linhas e transpor ele pra 111 colunas usando shell script.

Exemplo do arquivo:

0
0.3434545
0.6546456
0
0.6456456
0
0
...

Quando eu uso um arquivo com uma amostra de 100 linhas o comando abaixo funciona normal.

awk '{ORS=(NR%3?FS:RS)}1' FILE

Mas quando eu uso o arquivo fonte original (333 mil linhas) ele cria somente uma coluna, ou seja, fica como já esta.

O comando abaixo também funciona com um arquivo fonte de poucas linhas, mas quando uso o original o comando não suporta...

cat FILE | xargs - L111

Alguém poderia ajudar?


  


2. MELHOR RESPOSTA

luiz
luizsouza99

(usa Linux Mint)

Enviado em 27/09/2014 - 01:33h

Não é um comando, mas um script que faz o que você precisa.

Pegue as 333 mil linhas e divida para 111 arquivos que dará 3000 linhas cada um:
#!/bin/bash

mkdir $HOME/temp

UM=$"1"
DOI=$"3000"

VOLTA=$"0"
while [ $VOLTA -lt 111 ];do
VOLTA=$[$VOLTA+1]

# cria os arquivos de 1 a 111 já com as 3000 linhas escritas
cat seu_arquivo | sed -n ${UM},${DOIS}p > $VOLTA

# atualizando os valores das linhas
UM=$[$UM+3000]
DOIS=$[$DOIS+3000]
done


Agora ele pega as 10 primeiras linhas de cada um dos 111 arquivos e joga em outro arquivo, depois disto é só aplicar o seu comando, para ficar na ordem correta o seu comando deve criar 111 colunas com 10 linhas.
# tratando os dados de 10 em 10 na ordem
TRES=$"1"
QUATRO=$"10"
echo > $HOME/permanente
echo > $HOME/temporario

# este loop faz o proximo loop escrever todas as linhas (rodando 300 vezes)
VOLTA_MEDIA=$"0"
while [ $VOLTA_MEDIA -lt 300 ];do
VOLTA_MEDIA=$[$VOLTA_MEDIA+1]

VOLTA2=$"0"
while [ $VOLTA2 -lt 111 ];do
VOLTA2=$[$VOLTA2+1]

# lê os arquivos de 1 a 111 e ordenando de 10 em 10
cat $HOME/temp/$VOLTA2 | sed -n ${TRES},${QUATRO}p >> $HOME/temporario

# atualizando os valores das linhas
TRES=$[$TRES+10]
QUATRO=$[$QUATRO+10]
done
# terminou de escrever, agora ele deve criar um arquivo com 111 colunas tendo 10 linhas e adicionando 10 linhas a cada rodada

# aplicando o seu comando, coloquei o endereço do arquivo temporário no lugar de FILE
awk '{ORS=(NR%3?FS:RS)}1' $HOME/temporário >> $HOME/permanente
done


Com este esquema nós conseguimos mastigar as 333 mil linhas para o computador dar conta, nós dividimos em 111 arquivos para que na hora de ordenar as linhas elas fiquem na mesma ordem em que ficariam quando você dá o comando puro.

Não testei o script, mas a lógica é esta, dá uma analisada nas linhas do script e veja se está compatível com a sua realidade, se tiver algum erro pode ser erro de sintax ou conta matematica errada, dá uma olhada, mas repito a lógica é esta.

Feedback hein cara, rsrs

3. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

Fernando
phoemur

(usa Debian)

Enviado em 26/09/2014 - 17:54h

Experimenta usar file descriptors que deve funcionar


exec 3<arquivo.txt; xargs -L111 <&3; exec 3<&-


e agora direcionando para um novo arquivo:

exec 3<arquivo.txt; xargs -L111 <&3 > arquivo_novo.txt; exec 3<&-



4. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

césar
cesarufmt

(usa Linux Mint)

Enviado em 26/09/2014 - 19:00h

phoemur escreveu:

Experimenta usar file descriptors que deve funcionar


exec 3<arquivo.txt; xargs -L111 <&3; exec 3<&-


e agora direcionando para um novo arquivo:

exec 3<arquivo.txt; xargs -L111 <&3 > arquivo_novo.txt; exec 3<&-


--

Phoemur, agradeço a ajuda. Mas infelizmente não deu certo. Aparece as seguintes mensagens:

xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
xargs: argument line too long

-----

Acredito que o problema acontece pelo número muito grande de linhas (333 mil)...

Continuo estudando uma forma de resolver isso...


5. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

césar
cesarufmt

(usa Linux Mint)

Enviado em 27/09/2014 - 10:15h

luizsouza99 escreveu:

Não é um comando, mas um script que faz o que você precisa.

Pegue as 333 mil linhas e divida para 111 arquivos que dará 3000 linhas cada um:
#!/bin/bash

mkdir $HOME/temp

UM=$"1"
DOI=$"3000"

VOLTA=$"0"
while [ $VOLTA -lt 111 ];do
VOLTA=$[$VOLTA+1]

# cria os arquivos de 1 a 111 já com as 3000 linhas escritas
cat seu_arquivo | sed -n ${UM},${DOIS}p > $VOLTA

# atualizando os valores das linhas
UM=$[$UM+3000]
DOIS=$[$DOIS+3000]
done


Agora ele pega as 10 primeiras linhas de cada um dos 111 arquivos e joga em outro arquivo, depois disto é só aplicar o seu comando, para ficar na ordem correta o seu comando deve criar 111 colunas com 10 linhas.
# tratando os dados de 10 em 10 na ordem
TRES=$"1"
QUATRO=$"10"
echo > $HOME/permanente
echo > $HOME/temporario

# este loop faz o proximo loop escrever todas as linhas (rodando 300 vezes)
VOLTA_MEDIA=$"0"
while [ $VOLTA_MEDIA -lt 300 ];do
VOLTA_MEDIA=$[$VOLTA_MEDIA+1]

VOLTA2=$"0"
while [ $VOLTA2 -lt 111 ];do
VOLTA2=$[$VOLTA2+1]

# lê os arquivos de 1 a 111 e ordenando de 10 em 10
cat $HOME/temp/$VOLTA2 | sed -n ${TRES},${QUATRO}p >> $HOME/temporario

# atualizando os valores das linhas
TRES=$[$TRES+10]
QUATRO=$[$QUATRO+10]
done
# terminou de escrever, agora ele deve criar um arquivo com 111 colunas tendo 10 linhas e adicionando 10 linhas a cada rodada

# aplicando o seu comando, coloquei o endereço do arquivo temporário no lugar de FILE
awk '{ORS=(NR%3?FS:RS)}1' $HOME/temporário >> $HOME/permanente
done


Com este esquema nós conseguimos mastigar as 333 mil linhas para o computador dar conta, nós dividimos em 111 arquivos para que na hora de ordenar as linhas elas fiquem na mesma ordem em que ficariam quando você dá o comando puro.

Não testei o script, mas a lógica é esta, dá uma analisada nas linhas do script e veja se está compatível com a sua realidade, se tiver algum erro pode ser erro de sintax ou conta matematica errada, dá uma olhada, mas repito a lógica é esta.

Feedback hein cara, rsrs


Luizsouza99, obrigado pela sua ajuda, vou estudar ele. =)

Consegui quebrar o arquivo em partes de 111 linhas: "split -l 111 file.txt a"

Isso gerou 3 mil arquivos, depois inseri eles em um banco transpondo as 111 linhas para 1 linha com 111 colunas. Assim deu certo meu objetivo.

Muito obrigado!


6. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

luiz
luizsouza99

(usa Linux Mint)

Enviado em 27/09/2014 - 14:02h

se a ordem não importar vc conseguiu o seu objetivo, mas vc tem que entender que dividindo em 111 linhas vc embaralhou os dados, já que com o comando "puro" por exemplo a linha 1 ficaria ao lado da linha 3001 e assim por diante.

vc disse que dividiu em 111 linhas gerando 3000 arquivos, mas na verdade são 111 arquivos gerando 3000 linhas em cada um.

o script já esta pronto eu só dividi ele em duas partes para poder explicar.


7. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

césar
cesarufmt

(usa Linux Mint)

Enviado em 27/09/2014 - 14:27h

luizsouza99 escreveu:

se a ordem não importar vc conseguiu o seu objetivo, mas vc tem que entender que dividindo em 111 linhas vc embaralhou os dados, já que com o comando "puro" por exemplo a linha 1 ficaria ao lado da linha 3001 e assim por diante.

vc disse que dividiu em 111 linhas gerando 3000 arquivos, mas na verdade são 111 arquivos gerando 3000 linhas em cada um.

o script já esta pronto eu só dividi ele em duas partes para poder explicar.


----

Luizsouza99, o split salvou na ordem correta. A ordem é extremamente importante, cada conjunto de 111 linhas se refere a 1 dia.

lista10.txt
1
2
3
4
5
6
7
8
9
10

split -l 3 lista10.txt a

cria os arquivos:

aaa
aab
aac
aad

conteúdo:

aaa=123
aab=456
aac=789
aad=10

---------------------------

Luizsouza99, estou estudando seu código. Fiquei empacado em 2 pontos.

1 - Fazer o sed ler um intervalo com variáveis de inicio e fim. Sempre da erro com a ",".
2 - A parte que cria os arquivos. Não esta criando.

Vou continuar tentando....

Obrigado!


8. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

luiz
luizsouza99

(usa Linux Mint)

Enviado em 27/09/2014 - 15:28h

1- estranho eu testei antes de colocar no script e funcionou, qualquer coisa é só vc usar uma váriavel e extrair o valor desta variavel a cada rodada de um arquivo texto, ou seja as quantidades ficarão gravados neste arquivo e a cada rodada o sed pega uma linha deste arquivo.

2- é só vc colocar o comando touch que não deve ter erro, aqui usando o ">" ele cria os arquivos normalmente.

de qualquer forma se vc conseguiu fazer de uma forma mais simples, não fica quebrando a cabeça com meu script não, se a lógica te ajudou, já esta bom demais


9. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

césar
cesarufmt

(usa Linux Mint)

Enviado em 28/09/2014 - 11:20h

luizsouza99 escreveu:

1- estranho eu testei antes de colocar no script e funcionou, qualquer coisa é só vc usar uma váriavel e extrair o valor desta variavel a cada rodada de um arquivo texto, ou seja as quantidades ficarão gravados neste arquivo e a cada rodada o sed pega uma linha deste arquivo.

2- é só vc colocar o comando touch que não deve ter erro, aqui usando o ">" ele cria os arquivos normalmente.

de qualquer forma se vc conseguiu fazer de uma forma mais simples, não fica quebrando a cabeça com meu script não, se a lógica te ajudou, já esta bom demais



luizsouza99, a estrutura abaixo deu certo com você?

cat seu_arquivo | sed -n ${UM},${DOIS}p > $VOLTA


10. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

luiz
luizsouza99

(usa Linux Mint)

Enviado em 28/09/2014 - 18:06h

deu certo, eu criei um script só pra ele e fui testando até encontrar a sintax que funcionasse


11. Re: Shell script pra transpor milhares de linhas em 111 colunas [RESOLVIDO]

luiz
luizsouza99

(usa Linux Mint)

Enviado em 01/10/2014 - 01:38h

E como a filosofia do Linux é boa, todos se ajudando.

Não estava conseguindo finalizar um script hoje, para o sort funcionar eu deveria usar linhas, mas para exibir o resultado na tela deveria se em sequência.

E acabei encontrando a solução neste tópico mesmo, com o comando xargs que eu nem sabia que existia.

cat arquivo | sort -n | xargs echo



Viva o Linux!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts