Como dividir um arquivo alternando o prefixo usado para os arquivos de saída?

4

Eu tenho um arquivo grande. É feito de partes de 40 linhas cada. Existem dois tipos de partes e elas se alternam. Os dois tipos de peças devem ser numerados de forma independente. Portanto, a primeira parte deve ser X_0001 , a segunda parte deve ser Y_0001 , depois X_0002 , Y_0002 , etc.

Eu usei este comando, mas ele só pode ser dividido em partes com o mesmo prefixo:

 split -d -l 40 -a 4  inputfile X_ 
    
por Mohsen El-Tahawy 29.07.2016 / 00:50

2 respostas

2

Com gnu split você pode usar a opção --filter :

split --numeric-suffixes=0001 -l 80 -a 4 \
--filter='sed -n -e "1,40w $FILE" -e "41,80w ${FILE/X/Y}"' infile X_

Isso dividirá o arquivo em partes de 80 linhas, canalizando o conteúdo de cada parte para sed , que grava as primeiras 40 linhas em $FILE (o nome da peça, nesse caso split substitui por X_???? - consulte man split ) e o restante a ${FILE/X/Y} , que é o mesmo nome, mas com X substituído por Y .

Como o requisito foi alterado e você só precisa dividir em partes com nomes alternados, você também pode usar awk :

awk 'BEGIN{c=1;p="X"}
{close(fn);fn=sprintf("%s_%04d", p, c);print >> fn} 
NR%40==0{p="Y"}NR%80==0{p="X";c++}' file1

Isso define o nome da peça com base em duas variáveis, p refix e c ounter. A cada 40 linhas, o p refix muda para Y , a cada 80 linhas o p refix muda para X e o c ounter é incrementado.

    
por 29.07.2016 / 01:16
2

Uma maneira é usar split e renomear os arquivos depois.

Mas o mais simples é provavelmente chamar o awk. Você pode usar o operador de redirecionamento > para gravar em um arquivo em vez da saída padrão. A variável NR contém o número da linha atual.

O redirecionamento do Awk cuida automaticamente da abertura de arquivos. Você deve fechar os arquivos explicitamente se usar muitos diferentes, caso contrário, você pode ter um limite em arquivos abertos.

awk '
  (NR-1) % 40 == 0 { close(out); out = sprintf("%s_%04d", (NR % 80 == 1 ? "X" : "Y"), NR/80+1); }
  { print >out }
' inputfile
    
por 29.07.2016 / 01:06