Eu tenho um grande arquivo de entrada de genótipo de contagem de arquivo. Aqui estão as primeiras linhas:
LocusID f nAlleles x y
2L:8347 1 2 44.3166 -12.2373
2L:8347 1 2 39.2667 -6.8333
2L:31184 1 2 39.2667 -6.8333
2L:31184 1 2 39.2667 -6.8333
2L:42788 1 2 39.2667 -6.8333
2L:42788 1 2 39.2667 -6.8333
2L:42887 1 2 39.2667 -6.8333
2L:42887 1 2 39.2667 -6.8333
A primeira coluna é o ID do locus e para cada locus tenho duas linhas com IDs de locus idênticos. Eu quero manter apenas aqueles cuja coluna x e coluna y não são qualificadas para cada locus.
aqui está minha saída desejada do exemplo acima
out
2L:8347 1 2 44.3166 -12.2373
2L:8347 1 2 39.2667 -6.8333
Alguma ideia de como posso fazer?
Testado. Se os cabeçalhos das colunas NÃO estiverem realmente presentes no arquivo, exclua a linha BEGIN.
Deveria ser um comentário para Ed Morton, mas muito grande e possivelmente de interesse mais geral.
Eu escrevi um trabalho simples de cinco minutos para um OP que não conseguiu começar, depois de ver dois comentários inúteis. Não estou muito impressionado com sua referência, que contém alternativas que induzem ao vômito, como:
Eu apontei que técnicas melhores são possíveis, e postei e testei o código.
É claro que getline não é necessário aqui, mas fornece uma certa simetria às operações. Se você confia no ciclo awk, acaba usando algo como FNR % 2 == 1 para lidar com as linhas estritamente alternadas. Isso é péssimo, portanto, prefiro ignorar os OPs "duas linhas" e agrupar linhas pelo LocusID, para generalidade.
Eu dignifico scripts awk postando-os em variáveis de shell porque eles lêem melhor. Eu detesto um grande código awk colocado na linha de comando e dobrado em lugares estranhos. Além disso, isso realmente corta o SysAdmins porque todo o awk aparece em um ps -ef e arrasta a saída (no SunOS costumava travar o ps porque tinha um comprimento de linha máximo fixo).
Meu idioma usual para evitar isso no bash seria:
que ps lista como awk -f /dev/fd/63, escondendo convenientemente meu código proprietário do curioso.
Eu nunca divido o comando shell do awk: eu nunca uso um arquivo .awk. Uma de duas coisas ruins vai acontecer:
(a) Você fornece o arquivo .awk e espera que o usuário digite o comando awk (possivelmente incluindo '-F|' ou alguma outra opção), e ele VAI errar.
(b) Você fornece ao usuário um .sh e um .awk, e há um problema de atualização e ele acaba com uma inconsistência entre os arquivos.
Pelas mesmas razões, se eu precisar fornecer uma página man, eu a incorporo no próprio script, como funções chamadas Uso e Ajuda, contendo documentos Here.
Estou bem ciente de que ''' ... ''' não é necessário. No entanto, eu me cansei de postar soluções com aspas simples e as pessoas pensarem "Falta citação lá, vou corrigi-lo", estragando meu post testado e depois reclamando que não funcionou. Ofuscá-lo com algumas strings vazias impede as pessoas de mexer com ele e aumenta a visibilidade.
Após 40 anos no Unix, conheço as variáveis reservadas em shell e awk. Eu tenho boas regras para nomenclatura, mas para um problema trivial, prefiro usar termos que o OP possa intuir. Duas linhas, dois vetores. Eu uso caps para muitas variáveis de shell para visibilidade para distingui-las das palavras-chave. Qualquer um pode escrever palavras-chave: quase todos os bugs são porque os codificadores não veem os dados, eles não acentuam o papel das variáveis.
A Getline não falha de maneiras inesperadas para mim, porque sei o que esperar. Você pode não gostar das expressões idiomáticas que uso, mas isso não as torna erradas. São soluções para problemas que tenho visto ao longo de muitos anos.
Meu conselho: transforme os espaços em vírgulas para que você tenha um CSV e depois carregue-o em um banco de dados.
Usando
psql
e Postgres e o arquivo que você deu comotemp.csv
este se parece com: