Usando dados CSV com awk

Estou tentando encontrar uma maneira de pegar os dados individuais de um arquivo CSV e usá-los como uma variável em um grep ou comando awk. Qualquer um dos dois parece apropriado, mas não tenho certeza de como dizer para fazer isso de maneira adequada.

Por exemplo, tenho um conjunto de dados no formato TSV que se parece com este:

ID Name Eye Color 1 Bill Blue 2 Sam Blue 3 Fred Brown 4 Joe Brown 5 Ted Blue 6 Bob Brown 

Este não é o conjunto de dados real, mas se comporta da mesma maneira. Este é todo o banco de dados de ligação de proteínas, o TSV tem 300 MB com milhões de entradas e dezenas de colunas, então não posso” t limpo inclua a coisa real.

Quero fazer um arquivo contendo as linhas de indivíduos que têm olhos azuis, então criei um arquivo CSV que é feito de " ID " coluna, que, neste caso, seria assim:

1, 2, 5

Este CSV contendo o " ID " foi gerado usando o " Grep " para pesquisar o termo-chave.

No final das contas, quero um arquivo TSV parecido com este: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Mas não consigo parecer para descobrir como fazer isso. Posso criá-lo individualmente para cada entrada usando awk ou grep e incluindo o número de ID como um critério. No entanto, o CSV que estou usando tem 1200 entradas, então gostaria de automatizar esse processo.

Abaixo está o código que produzirá o resultado desejado para uma única entrada, mas quero usar os números de ID para pesquisar automaticamente.

O BindindDB_All.tsv é meu arquivo de origem, com vários milhões de entradas. Isso produzirá um TSV chamado " new.tsv " e contém a linha inteira do arquivo BindindDB_All.tsv onde o ID (na coluna 1) é igual a 66106.

awk "$1 == 66106" BindingDB_All.tsv >> new.tsv 

Eu gostaria de fazer algo assim:

awk "$1 == ID.csv" BindingDB_All.tsv >> new.csv 

onde seria lido cada ID, imprima a linha para new.csv, leia a próxima ID e faça o mesmo.

O arquivo CSV contém 1200 termos de pesquisa, para serem comparados com vários milhões de possibilidades, cada um com um ID exclusivo. precisa dele para pesquisar SOMENTE a coluna 1, pois encontrará o ID em outra variável es em cada linha.

Para resumir, preciso olhar na coluna 1 da linha, compará-lo com o primeiro número em meu arquivo CSV e ver se é uma correspondência. Se não for uma correspondência, ele precisará verificar a próxima linha na coluna 1 e assim por diante até encontrar a correspondência. Quando encontrar a linha em que a coluna 1 corresponde ao primeiro ponto de dados CSV, quero que a linha seja gerada. Em seguida, quero repetir para a segunda entrada no CSV, até encontrar todas as 1.200 linhas.

Alguma ideia? Parece um problema de loop, mas também não sei como fazer isso funcionar.

EDITAR:

Visto que as pessoas ainda parecem dispostas a ajudar, deixe-me tentar responder às perguntas que foram postados.

Aqui estão as 6 primeiras entradas dos meus dados reais, contendo números de ID que serão usados como parâmetros de pesquisa.

66106 66107 66108 66109 66110 50127715 

Não há nomes de coluna, nem outros dados. Esses são valores que desejo pesquisar individualmente em um arquivo diferente, um TSV. Também falei errado quanto ao tamanho do TSV, tenho um TSV de 4 GB, que se compacta para 300 MB. O arquivo contém mais entradas do que qualquer um dos meus programas permite visualizar. Abaixo está um exemplo de uma única entrada de vários milhões. PRECISO que todos esses dados sejam extraídos de uma vez, portanto, cortá-los não é um opção.

50127715 CCCC (CCC) c1nc2N3 [C @ H] 4CCC [C @ H] 4N = C3N (C) C (= O) c2 [nH] 1 InChI = 1S / C18H27N5O / c1- 4-7-11 (8-5-2) 15-20-14-16 (21-15) 23-13-10-6-9-12 (13) 19-18 (23) 22 (3) 17 ( 14) 24 / h11-13H, 4-10H2,1-3H3, (H, 20,21) / t12-, 13 + / m1 / s1 CSRSQF SFDXYRFV-OLZOCXBDSA-N 50073697 5-metil-2- (1-propilbutil) – (6aR, 9aS) -3,4,5,8-tetrahidrociclopenta [4,5] imidazo [2,1-b] purin-4- one :: CHEMBL280307 Fosfodiesterase 1 Bos taurus 60 ChEMBL 10.1016 / s0960-894x (98) 00681-7 9990447 Ho, GD Silverman, L Bercovici, A Puchalski, C Tulshian, D Xia, Y Czarniecki, M Green, M Cleven, R Zhang, H Fawzi, A Schering-Plough Research Institute http://www.bindingdb.org/bind/chemsearch/marvin/MolStructure.jsp?monomerid=50073697 http://www.bindingdb.org/jsp/dbsearch/PrimarySearch_ki.jsp?energyterm=kJ/mole&tag=pol&polymerid=49000914&target=Phosphodiesterase+1&column=ki&startPg=0&Increment=50&submit=Search http://www.bindingdb.org/jsp/dbsearch/PrimarySearch_ki.jsp?energyterm=kJ/mole&tag=r21&monomerid=50073697&enzyme=Phosphodiesterase+1&column=ki&startPg=0&Increment=50&submit=Search 44272162 103967010 CHEMBL280307 ZINC28221715 1 MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS dependente de cálcio / calmodulina 3″ , 5″ -nucleotídeo fosfórico cíclico odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Não tenho certeza de como fazer isso lido como um TSV nesta caixa, mas 50127715 é a primeira coluna, a coluna ID. Desejo ter meu arquivo CSV inicial, contendo os números de ID de interesse, pesquisar o grande TSV um número de ID de cada vez na primeira coluna. Se o número estiver na primeira coluna, quero que ele grave essa linha em um arquivo e, em seguida, busque a próxima ID. Quero todos os resultados em um único arquivo.

Tenho certeza de que em todas as minhas etapas para chegar aqui, há uma maneira mais fácil de fazer isso, mas claramente não tenho certeza de como fazer mais claro. Quero pesquisar no TSV grande por " 66106 " na coluna 1 e quando encontrar a linha para escrever a linha inteira um arquivo. Em seguida, pesquise " 66107 " e, assim que o encontrar, adicione-o ao mesmo arquivo. Dessa forma, tenho um único arquivo, pode ser um CSV ou TSV, com 1200 entradas em vez de vários milhões.

Comentários

  • Por que não apenas analisar o TSV diretamente? awk -F '\t' separará os campos de entrada por guias. De fato, por padrão, awk separará os campos por espaços em branco coníguos. Portanto, para obter todas as pessoas de olhos azuis (e preservar o cabeçalho), você só precisa de awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Tentei executar este comando em um arquivo de amostra chamado " test.tsv ", com a mesma entrada listada acima, porém produziu uma saída incomum. Ele apenas substituiu todas as cores dos olhos por " Azul " enquanto todo o resto permaneceu o mesmo.
  • $3 = "Blue" deve ser $3 == "Blue". O primeiro é uma tarefa, o último é uma comparação.
  • Este é um CSV ou TSV?
  • Distribuir as informações sobre seus requisitos uma localização atual por vez não é ' uma boa abordagem para obter uma boa solução. Por favor, edite sua pergunta para fornecer um exemplo mais representativo do que você ' está tentando fazer. Inclua um arquivo TSV, um arquivo CSV e os arquivos de saída esperados que você espera como entrada. Certifique-se de cobrir todos os seus casos de uso, por exemplo, se todas as correspondências são contra valores em 1 coluna ou correspondências diferentes em colunas diferentes, etc. Consulte Como perguntar .

Resposta

$ awk -F"\t" "(NR==1) || ($3=="Blue")" file ID Name Eye Color 1 Bill Blue 2 Sam Blue 5 Ted Blue 

Parece que o que você está realmente tentando fazer, no entanto, é criar um novo arquivo por ID que, assumindo que os IDs são únicos como no seu exemplo, seria:

awk -F"\t" "{ out="out_" $1 ".txt"; print > out; close(out) }" BindingDB_All.tsv 

ou se você quiser que cada arquivo de saída inclua o cabeçalho:

awk -F"\t" " NR==1 { hdr=$0; next } { out="out_" $1 ".txt"; print hdr ORS $0 > out; close(out) } " BindingDB_All.tsv 

Comentários

  • Eu editei para maior clareza, mas na verdade quero apenas 1 arquivo contendo esses nomes. Devido à natureza dos dados serem enormes, tentei apenas fazer um conjunto de exemplos para fins de demonstração, mas eu ' sou novo em programação, então ' Não tenho certeza se ' estou expressando adequadamente o que preciso.

Resposta

Para qualquer um que possa encontrar isso no fu ture, eu tenho uma solução. A primeira coisa que fiz foi converter o TSV em CSV usando:

sed "s/\t/,/g" filename_with_tabs > filename_with_commas.csv 

Então, para pesquisar o código do meu arquivo que estava procurando é:

awk -F, "FNR==NR {h[$1] = $0; next} {print $0,h[$1]}" file1 file2 > new_file.csv 

Isso pesquisará a primeira coluna para o texto contido em um CSV separado. Nesse caso, " file1 " é o arquivo a ser pesquisado e " file2 " contém as strings a serem pesquisadas. Ambos os arquivos estão no formato CSV.

Isso produziu um arquivo CSV separado que continha todas as linhas dentro do arquivo1 que tinha um certo ID na coluna 1 que corresponde a um dos IDs contidos no arquivo2.

Espero que ajude alguém algum dia, porque isso tem destruído meu cérebro por semanas. Eu nem mesmo encontrei a solução, meu chefe teve que me mostrar.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *