separe um arquivo em vários arquivos pequenos de acordo com colunas

2

Eu tenho um arquivo de dados, que pode ter N linhas, e cada linha é composta por elementos M separados por espaço em branco. Atualmente, quero separar cada linha em vários segmentos. Em outras palavras, suponha que o número de segmentos seja 3; então o arquivo original será separado em 3 arquivos, cada um com N linhas e cada linha com elementos M / 3. Além de escrever o programa C ++ ou Java, existe alguma abordagem eficiente que possa cumprir essa tarefa no Unix / Linux?

    
por user288609 17.02.2012 / 04:14

4 respostas

1

Isso serve para um número variável de campos no mesmo arquivo, e o último segmento é apenas parcialmente preenchido, ou seja, menos campos do que o especificado (por segmento). Observe, porém, que se o número de campos em uma linha resultar em menos segmentos do que o especificado, nada será gravado no arquivo de saída para esses segmentos de déficit.

awk -v 'ncol=5' -v 'pfix=file' '{
    fldn = 0
    sfix = 1
    segs = NF/ncol
    # round up if number of field is not evenly divisible by number of columns    
    segs = (segs == int(segs)) ?segs :int(segs)+1   
    while (fldn != NF) {
        fmod = (++fldn) % ncol
        printf "%s%s", dlim, $(fldn) >> pfix sfix 
        if (fmod == 1 ) { dlim = " " }
        if ((fmod==0 ) || (fldn==NF))  { 
            printf "\n" >> pfix sfix 
            dlim = ""; sfix++ 
        }
    } 
}' infile
    
por 17.02.2012 / 08:37
1

É isso que você está procurando?

awk '{ print $1 $2 $3 > file1; print $4 $5 $6 > file2; print $7 $8 $9 > file3 }' originalfile

Ou você queria algo mais geral?

awk -v 'n=3' -v 'prefix=pref' '{
    for (i = 0; i < n; i++) {
        for (j = 0; j < NF / n; j++) {
            printf("%s ", $(i + j + 1)) > prefix i
        }
        printf("\n") > prefix i
    }
}' originalfile

Nota: isso pressupõe que todas as linhas tenham o mesmo número de colunas.

    
por 17.02.2012 / 04:19
0

Se o seu arquivo estiver limpo, aconselho usar o aplicativo padrão cut

cut tem três sinalizadores que você deve saber pelo menos

  • -d para definir o delimitador (TAB é o padrão
  • -f para selecionar o campo
  • -c para selecionar um intervalo de caracteres

Você pode optar por usar a combinação -d -f ou -c Se o seu arquivo não é delimitado por TAB, mas bem delimitado por espaço, você pode fazer

cut -d' ' -f1-3

para selecionar as três primeiras colunas.

Se você quiser selecionar a quarta coluna, entre os caracteres 25 e 36, você pode fazer

cut -c25-36
    
por 17.02.2012 / 07:53
0

sep_file.ksh

#!/bin/ksh

FILENAME=$1
SEG=$2

SEG_NO=1

while [[ $SEG_NO -le $SEG ]]
do
  awk '{CL=NF/'"$SEG"';CL=(CL==int(CL)?CL:int(CL)+1);LS=(('"$SEG_NO"'-1)*CL)+1;LE=LS+CL-1;if(LE>NF)LE=NF;for(i=LS;i<=LE;i++)printf("%s ",$i);printf("\n")}' $FILENAME > ${FILENAME}_$SEG_NO
  SEG_NO='echo "$SEG_NO + 1"|bc'
done

Uso: ./sep_file.ksh <file_name_to_read> <no_of_segments>

    
por 17.02.2012 / 08:01