Como dividir um arquivo baseado em uma lista de padrões e nomear os arquivos de saída como padrão?

3

O arquivo 1 se parece com isso (via metabólica: gene):

A: 1
A: 2
A: 3
B: um
B: b
C: pp
D: rr

Como obter um arquivo de saída que se parece com isso (nomeado como File1.new):

A: 1, 2, 3
B: a, b
C: pp
D: rr

Eu sou um iniciante em Linux. Explicações fáceis são preferíveis!

    
por Saisha 03.03.2017 / 08:26

3 respostas

0

Com datamash do GNU

datamash -t: groupby 1 collapse 2 < file
A:1,2,3
B:a,b
C:pp
D:rr

Se você quiser as contagens também,

datamash -t: groupby 1 collapse 2 count 2 < file
A:1,2,3:3
B:a,b:2
C:pp:1
D:rr:1

Você também pode countunique se quiser o número de campos exclusivos.

    
por 03.03.2017 / 14:04
3

este é um trabalho para o awk.

awk -F: '{L[$1]=L[$1] "," $2} 
    END { for (l in L) printf "%s:%s\n",l,substr(L[l],2);}'

onde

  • -F: use : como separador
  • {L[$1]=L[$1] "," $2} armazena valor separado por vírgula indexado pelo campo 1
  • END no final do arquivo
  • for (l in L) loop através dos valores
  • printf "%s:%s\n",l,substr(L[l],2); print, pulando a primeira vírgula
  • você pode usar "," ou ", " , ajuste a subseqüência final de acordo.

o awk pode ser alinhado, use

awk -F: '....' File1 > File3

para contar o gene simplesmente adicione var tou tou (aqui G).

{L[$1]=L[$1] "," $2;G[$1]++} 
END { for (l in L) printf "%s:%s:%d\n",l,substr(L[l],2),G[l];}
    
por 03.03.2017 / 11:28
0

Estrutura de dados

 %h = (
     ...
      B => [a, b],
      A => [1, 2, 3],
     ...
 );


perl -F':' -lane '
   push @{$h{$F[0]}}, $F[1]}{
   $"=",";
   print "$_:", "@{$h{$_}}|", scalar @{$h{$_}} for keys %h;
' File1 > File1.new

Breve

The field separator is set to a semicolon, thus populating each time a line is read in afresh 
the @F array. Then we append the 2nd field, $F[1], to the array of hash
keyed in on the 1st field, $F[0]. At the end, we display the key name,
followed by the array contents corresponding to this key, & the count of
the array as well.

Saída

A:1,2,3|3
B:a,b|2
C:pp|1
D:rr|1

Sed

sed -e '
  :loop
     $!N
     s/^\(\([^:]*\):.*\)\n:\(.*\)/,/
   tloop
   P;D
' yourfile
    
por 03.03.2017 / 12:37