Usando awk
:
awk 'NR == 1 {print $0}; NR > 1 {for(i=0;i<24;i++) print $0}' InputFile
Eu tenho dados diários que desejo duplicar em dados de 24 horas mantendo o valor igual para a etapa de tempo por hora. Meus dados se parecem com:
day Value
01/01/2012 2
01/02/2012 3
Então eu quero que a saída seja:
Day Value
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
01/01/2012 2
.
.
.
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
01/02/2012 3
.
.
.
i.e. 24 vezes por dia.
Usando awk
:
awk 'NR == 1 {print $0}; NR > 1 {for(i=0;i<24;i++) print $0}' InputFile
Se você colocar as linhas acima em um arquivo chamado sample.txt
, poderá usar tail
, xargs
e printf
para fazer isso:
$ cat <(head -1 sample.txt) <(tail -n +2 sample.txt \
| xargs -I{} printf "{}\n%.0s" {1..25})
Supondo que você tenha o seguinte tipo de arquivo.
$ more sample.txt
day Value
01/01/2012 2
01/02/2012 3
O head
preservará a linha de cabeçalho de sample.txt
:
$ head -1 sample.txt
day Value
O tail
faz o seguinte:
$ tail -n +2 sample.txt
01/01/2012 2
01/02/2012 3
O xargs
pega cada linha do arquivo e chama printf
para imprimi-las em número de vezes X, em que o intervalo {1..25}
produz a contagem.
O cat <(...) <(...)
coloca tudo junto.
De forma semelhante à primeira, é ligeiramente diferente. Em vez de usar as subshells e o cat
para a construção final da saída, ele usa um único subshell que encadeia a saída dos vários comandos juntos. Ele também faz uso de uma abordagem mais tradicional de usar um loop while
para percorrer cada linha do arquivo de entrada, sample.txt
. Ele novamente usa a mesma técnica de remover a segunda linha, usando tail
.
$ (head -1 sample.txt; while read i ; do seq 25 \
| xargs -i -- echo $i ; done < <(tail -n +2 sample.txt))
O formulário é o seguinte:
$ ( ... ; while .... done <(tail ...) )
Os parens exteriores agem como o cat
no primeiro exemplo, colocando todas as saídas s juntas.
O OP perguntou como modificar essa solução para que ela pudesse ser usada para processar mais de 1000 arquivos. Quebra automática do bloco de método de código # 1, por exemplo, renderia algo assim:
#!/bin/bash
for file in *.txt; do
cat <(head -1 $file) <(tail -n +2 $file | xargs -I{} printf "{}\n%.0s" {1..25}) | tee new_$file
done
Isso fará o loop de todos os arquivos denominados *.txt
e os gravará em arquivos denominados new_*.txt
. Isso pode ser adaptado conforme necessário.
Tags scripting