manter apenas as colunas no primeiro arquivo que seus números de coluna correspondem aos números no segundo arquivo

3

Eu tenho um genotype.file com 317 colunas (1, 2, 3, ..., 317). No exemplo abaixo, estou mostrando apenas as primeiras colunas!

Entrada genotype.file :

Chr00c0002  56240   N   N   N   A   N   A   N   N   N   N   N   A   
Chr00c0040  55087   N   N   N   C   N   N   N   N   N   N   N   N   
Chr00c0041  24730   N   N   N   A   N   A   N   N   N   N   N   N   
...

Eu quero manter apenas as colunas que correspondem a cada um dos meus count.files . Este é um dos meus arquivos de contagem e eu tenho no total 50 count file (count.file.1, count.file.2, ..., count.file.50)!

cat count.file.1
51
92
166
169
196
199
213
228
229
284
291
297

Portanto, para o primeiro count.file , quero manter apenas as colunas 51, 92, 166, 169, ... do genotype.file .

    
por Anna1364 06.10.2017 / 20:42

2 respostas

2

Supondo que o arquivo genotype.file seja delimitado por tabulações:

cut -f $(tr '\n' ',' <count.file.1 | sed 's/,$//') genotype.file

A substituição do comando, $( tr ... | sed ... ) , gera uma lista de números de colunas delimitados por vírgulas para cut a ser cortada do arquivo de entrada.

O tr substitui todas as novas linhas por vírgulas no arquivo count.file.1 , enquanto sed remove a vírgula extra no final.

O comando resultante será semelhante ao seguinte, dados dados de exemplo:

cut -f 51,92,166,169,196,199,213,228,229,284,291,297 genotype.file

Para fazer um loop pelos arquivos count.file.* :

for cfile in count.file.*; do
    cut -f $(tr '\n' ',' <"$cfile" | sed 's/,$//') genotype.file >genotype-"${cfile##*.}"
done

Isso cria um novo arquivo chamado genotype-N , em que N é o número correspondente ao count.file.N que foi usado para gerá-lo a partir de genotype.file . O número é extraído do final do nome do arquivo.

Se genotype.file não for delimitado por tabulações , poderá torná-lo delimitado por tabulações:

tr -s ' ' '\t' <genotype.file >genotype.tsv

Isso pressupõe que as colunas no arquivo original são separadas por apenas espaços. O comando tr substituirá vários espaços consecutivos por uma guia. O resultado é redirecionado para um novo arquivo. Você usaria o comando cut acima neste novo arquivo.

Usando awk

awk 'NR == FNR { c[++n] = $0; next } { t=$c[1]; for (i=2; i<=n; ++i) t = t OFS $c[i]; print t }' count.file.1 genotype.file

Isso primeiro lerá count.file.1 para obter as colunas que gostaríamos de extrair de genotype.file na matriz c e, em seguida, quando lermos genotype.file , esses números de coluna serão usados para extrair a dados. t é uma variável temporária que contém a linha de saída construída a partir das colunas selecionadas.

Para fazer um loop pelos arquivos count.file.* :

for cfile in count.file.*; do
    awk 'NR == FNR { c[++n] = $0; next } { t=$c[1]; for (i=2; i<=n; ++i) t = t OFS $c[i]; print t }' \
        "$cfile" genotype.file >genotype-"${cfile##*.}"
done

Isso cria um novo arquivo chamado genotype-N da mesma maneira que com a cut solution.

    
por 06.10.2017 / 22:30
1

Usando awk apenas com script simples.

awk '{ printf "{ print ";for(i=1; i<NF; i++){ printf "$%d, ",$i};
       print "$"$i" }" }' <<< "$(awk '{printf $0" "}' count.file.{1..50})" >genotype.awk

Isso produzirá um script awk chamado genotype.awk como abaixo, que coletará todos os números de colunas em todos os arquivos count.file.{1..50} . Usamos Brace Expansion aqui para ler todos esses 50 arquivos por awk .

{ print $51, $92, $166, $169, $196, $199, $213, $228, $229, $284, $291, $297, ... }

Uso:

awk -f genotype.awk genotype.file

Isso executará a execução do script genotype.awk no arquivo genotype.file e imprimirá apenas o número de colunas incluído.

    
por 06.10.2017 / 22:54