Använda CSV-data med awk

Jag försöker hitta ett sätt att ta enskilda data från en CSV-fil och använda den som en variabel i en grep eller awk-kommando. Antingen verkar lämpligt men jag är inte säker på hur jag ska säga att den ska göra det på lämpligt sätt.

Till exempel har jag en dataset i TSV-format som ser ut så här:

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

Detta är inte den faktiska datasetet, men fungerar på samma sätt. Detta är hela proteinbindningsdatabasen, TSV är 300 MB med miljontals poster och dussintals kolumner, så jag kan inte rent inkludera den riktiga saken.

Jag vill skapa en fil som innehåller raderna med individer som har blåa ögon, så jag har skapat en CSV-fil som består av " ID " kolumn, som i det här fallet skulle se ut så här:

1, 2, 5

Denna CSV som innehåller " ID " skapades med " Grep " kommando för att söka efter nyckelordet.

Jag vill till sist ha en TSV-fil som ser ut så här: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Men jag kan inte verka att klura ut hur man gör det. Jag kan skapa den individuellt för varje post med awk eller grep och inkludera ID-numret som ett kriterium, men CSV jag använder har 1200 poster så jag vill automatisera denna process.

Nedan är koden som ger det önskade resultatet för en enskild post, men jag vill använda ID-numren för att söka automatiskt.

BindindDB_All.tsv är min källfil, med flera miljoner poster. Detta ger en TSV som heter " new.tsv " och innehåller hela raden i BindindDB_All.tsv-filen där ID (i kolumn 1) är lika med 66106.

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

Jag skulle vilja göra något så här:

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

där det skulle läsa varje ID, skriv ut raden till new.csv, läs sedan nästa ID och gör detsamma.

CSV-filen innehåller 1200 söktermer, som kan jämföras med flera miljoner möjligheter, var och en med ett unikt ID. behöver det ENDAST söka i kolumn 1, eftersom det kommer att hitta ID inom andra variabler es i varje rad.

För att sammanfatta, behöver jag det för att titta i kolumn 1 i raden, jämföra det med det första numret i min CSV-fil och se om det är en matchning. Om det inte är en matchning måste den kontrollera nästa rad i kolumn 1 och så vidare tills den hittar matchningen. När den hittar raden där kolumn 1 matchar CSV: s första datapunkt, vill jag att den ska mata ut raden. Då vill jag att den ska upprepas för den andra posten i CSV, tills den har hittat alla 1200 rader.

Några idéer? Det låter som ett loopproblem men jag vet inte heller hur man får det att fungera.

REDIGERA:

Eftersom människor fortfarande verkar villiga att hjälpa, låt mig försöka svara på frågorna som har publicerats.

Här är de första 6 posterna av mina riktiga data, som innehåller ID-nummer som kommer att användas som sökparametrar.

66106 66107 66108 66109 66110 50127715 

Det finns inga kolumnnamn, inga andra data. Det här är värden som jag vill söka efter individuellt i en annan fil, en TSV. Jag har också felaktigt talat angående TSV-storleken, jag har en 4 GB TSV, som komprimeras till 300 MB. Filen innehåller fler poster än vad något av mina program gör att den kan jämnas. Nedan följer ett exempel på en enstaka post av flera miljoner. Jag BEHÖVER att alla dessa data dras på en gång, så att beskära det inte är en alternativ.

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 + / ml / s1 CSRSQF SFDXYRFV-OLZOCXBDSA-N 50073697 5-metyl-2- (1-propylbutyl) – (6aR, 9aS) -3,4,5,8-tetrahydrocyklopenta [4,5] imidazo [2,1-b] purin-4- en :: CHEMBL280307 Fosfodiesteras 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 44.272.162 103.967.010 CHEMBL280307 ZINC28221715 en MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS Kalcium / kalmodulinberoende 3″ , 5″ -cyklisk nukleotidfosf odiesteras 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Jag är inte säker på hur jag ska få detta att läsa som en TSV inom denna ruta, men 50127715 är den första kolumnen, ID-kolumnen. Jag vill ha min första CSV-fil, som innehåller de intressanta ID-numren, söka i det stora TSV-ID-numret åt gången i den första kolumnen. Om numret finns i den första kolumnen vill jag att den ska skriva den raden till en fil och sedan söka efter nästa ID. Jag vill ha alla resultat i en enda fil.

Jag är säker på att under alla mina steg för att komma hit finns det ett enklare sätt att göra detta, men jag är helt klart inte säker på hur man gör detta tydligare. Jag vill att den ska söka i den stora TSV efter " 66106 " inom kolumn 1, och när den hittar raden för att skriva hela raden i en fil. Sök sedan efter " 66107 " och när den hittar den lägger du till den i samma fil. På så sätt har jag en enda fil, kan vara en CSV eller TSV, med 1200 poster snarare än flera miljoner.

Kommentarer

  • Varför inte bara analysera TSV direkt? awk -F '\t' separerar inmatningsfält med flikar. Och awk skiljer faktiskt som standard fält med sammanhängande tomt utrymme. Så för att få alla blåögda personer (och bevara rubriken) behöver du bara awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Jag försökte köra det här kommandot på en exempelfil som heter " test.tsv ", med samma ingång som anges ovan, men det gav en ovanlig utdata. Det ersatte bara alla ögonfärger med " Blå " medan allt annat var detsamma.
  • $3 = "Blue" ska vara $3 == "Blue". Det förstnämnda är ett uppdrag, det senare är en jämförelse.
  • Är det här en CSV eller TSV?
  • Att rensa ut informationen om dina krav en brödsmulla i taget är inte ' en bra metod för att få en bra lösning. Vänligen redigera din fråga för att ge ett mer representativt exempel på vad du ' försöker göra. Inkludera en TSV-fil, en CSV-fil och de förväntade utdatafilerna du förväntar dig med tanke på den som inmatning. Se till att du täcker alla dina användningsfall, t.ex. om alla matchningar är mot värden i en kolumn eller olika matchningar i olika kolumner etc. Se Hur man frågar .

Svar

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

Det låter som det du verkligen försöker göra är dock att skapa en ny fil per ID som, förutsatt att ID: n är unika som i ditt exempel, skulle vara:

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

eller om du vill att varje utdatafil ska innehålla rubriken:

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

Kommentarer

  • Jag har redigerat det för tydlighetens skull, men jag vill egentligen bara ha en fil som innehåller de på grund av att data är enorma försökte jag bara skapa ett exempel för demonstrationsändamål, men jag ' är ny för programmering så jag ' jag är inte säker på om jag ' uttrycker ordentligt vad jag behöver.

Svar

För alla som kan hitta det här i fu tur, jag har en lösning. Det första jag gjorde var att konvertera TSV till en CSV med:

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

Sedan att söka efter min filkod jag letade efter är:

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

Detta söker i den första kolumnen efter texten i en separat CSV. I det här fallet är " file1 " filen du ska söka efter och " file2 " innehåller strängarna att söka efter. Båda dessa filer är i CSV-format.

Detta producerade en separat CSV-fil som innehöll alla raderna i fil1 som hade ett visst ID i kolumn 1 som matchar ett av ID: n som finns i fil2.

Jag hoppas att det hjälper någon någon gång, för det här har förstört min hjärna i flera veckor. Jag fick inte ens lösningen själv, min chef var tvungen att visa den för mig.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *