Melhor abordagem para gerar e adicionar conteúdo aos arquivos

1

Eu tenho um arquivo de entrada como abaixo.

1 First one
2 First two
3 First three
3 Second three

Estou gerando 2 arquivos de saída, como abaixo.

  #FILE1 
 1 First one
 2 First two
 3 First three
  #FILE2
 1 First one
 2 First two
 3 Second three

Eu tenho o código abaixo, que funciona perfeitamente bem para entradas menores.

containsElement () {
  local e
  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

declare -a InputIDs
touch file1.txt
while IFS=' ' read id value; do

             containsElement "$id" "${InputIDs[@]}"
             ret_val=$(echo $?)
             if [ "$ret_val" -eq 1 ]
             then
             #foreach file present in the directory, we need to add.
             for f in /home/ramesh/*; do
             echo "$id $value" >> $f;
             done
             else

             counter=0
             for f in /home/ramesh/*; do
             let counter=counter+1
             filename="$id.$counter"
             cp "$f" /home/ramesh/"$filename".txt
             sed -i '/^'$id'/d' /home/ramesh/"$filename".txt
             echo "$id $value " >> /home/ramesh/"$filename".txt
             done

O problema é que o script leva quase 15 minutos para executar entradas que possuem 50 valores. (de 50 valores, 15 são repetidos). Para os 50 valores, ele gerou 131,072 arquivos que, acredito, são o número total de combinações possíveis para minha entrada.

Existe uma abordagem melhor para implementar isso?

EDITAR:

Um exemplo mais complicado é o seguinte.

16250 somevalue in second column for all rows
16875 
17507 
17662 
18048 
18276 
18355 
20544 
23169 
158497 
160042 
163152 
163740 
164017 
164775 
165500 
166321 
166600 
166600 
166600 
166871 
167201 
169308 
169762 
169866 
170408 
171318 
171529 
171947 
173032 
174311 
174760 
177043 
177176 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
177783 
    
por Ramesh 10.03.2014 / 17:22

1 resposta

0

Solução em TXR :

(defstruct item nil
  id
  fields)

(let* ((items (build             ;; build list procedurally: goes with (add ...) below
                (awk ((plusp nf) ;; have at least one field
                      (fconv i)  ;; convert id field [f 0] to integer
                      (add (new item id (first f) fields (rest f)))))))
       (pitems (partition-by .id items))
       (combinations [apply maprod list pitems]))
  (each ((c combinations)
         (n (range 1)))
    (with-stream (*stdout* (open-file (fmt "file-~,06d" n) "w"))
      (each ((i c)) ;; item in combination
        (put-line '@{i.id} @{i.fields}')))))

Notas:

  • A macro awk é usada para inserir a entrada nos campos.
  • A macro build é usada para criar uma lista de item estruturas dos campos.
  • A função partição por agrupa a lista de itens em uma lista de -lists, onde as sub-listas consistem em itens consecutivos que compartilham o mesmo ID numérico.
  • A partir dessas partições, geramos combinações aplicando essas partições à função de mapeamento de produtos cartesianos maprod . As combinações de produtos são mapeadas através de list para apenas listá-las.
  • Depois disso, a tarefa é apenas iterar sobre as combinações de produtos, junto com um contador de incremento e, em seguida, despejar cada combinação em um arquivo separado. Os arquivos são nomeados file-NNNNNN (seis dígitos) para antecipar o caso quando houver mais de 130 mil.
por 13.07.2017 / 18:28