CSV-gegevens gebruiken met awk

Ik probeer een manier te vinden om de individuele gegevens uit een CSV-bestand te halen en deze als een variabele binnen een grep of awk commando. Beide lijken geschikt, maar ik weet niet zeker hoe ik het moet vertellen om dit op de juiste manier te doen.

Ik heb bijvoorbeeld een dataset in TSV-indeling die er als volgt uitziet:

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

Dit is niet de feitelijke dataset, maar gedraagt zich op dezelfde manier. Dit is de volledige proteïnebindingsdatabase, de TSV is 300 MB met miljoenen vermeldingen en tientallen kolommen, dus ik kan niet netjes voeg het echte werk toe.

Ik wil een bestand maken met de rijen met individuen met blauwe ogen, dus ik heb een CSV-bestand gemaakt dat bestaat uit het " ID " kolom, die er in dit geval als volgt uitziet:

1, 2, 5

Deze CSV met de " ID " is gegenereerd met de " Grep " commando om te zoeken naar de sleutelterm.

Ik wil uiteindelijk een TSV-bestand dat er als volgt uitziet: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Maar ik kan niet lijken uitzoeken hoe je dat doet. Ik kan het voor elk item afzonderlijk maken met awk of grep en het ID-nummer als criterium opnemen, maar de CSV die ik gebruik heeft 1200 items, dus ik zou dit proces graag willen automatiseren.

Hieronder staat de code dat het gewenste resultaat zal opleveren voor een enkele invoer, maar ik wil de ID-nummers gebruiken om automatisch te zoeken.

Het BindindDB_All.tsv is mijn bronbestand, met enkele miljoenen vermeldingen. Dit zal een TSV produceren met de naam " new.tsv " en bevat de volledige rij van het bestand BindindDB_All.tsv waarbij de ID (in kolom 1) gelijk is aan 66106.

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

Ik zou zoiets als dit willen doen:

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

waar het zou lezen elke ID, print de regel naar new.csv, lees dan de volgende ID en doe hetzelfde.

Het CSV-bestand bevat 1200 zoektermen, te vergelijken met enkele miljoenen mogelijkheden, elk met een unieke ID. I heb het ALLEEN nodig om kolom 1 te doorzoeken, omdat het de ID binnen andere variabl es in elke rij.

Om samen te vatten, ik heb het nodig om in kolom 1 van de rij te kijken, het te vergelijken met het eerste nummer in mijn CSV-bestand en te kijken of het een overeenkomst is. Als het geen overeenkomst is, moet het de volgende rij in kolom 1 controleren, enzovoort, totdat het de overeenkomst vindt. Als het de rij vindt waar kolom 1 overeenkomt met het eerste CSV-gegevenspunt, wil ik dat het de rij uitvoert. Dan wil ik dat het wordt herhaald voor het tweede item in de CSV, totdat het alle 1200 rijen heeft gevonden.

Enig idee? Het klinkt als een lusprobleem, maar ik weet ook niet hoe ik dat moet laten werken.

BEWERK:

Aangezien mensen nog steeds bereid lijken te helpen, wil ik proberen de vragen te beantwoorden die zijn gepost.

Hier zijn de eerste 6 vermeldingen van mijn echte gegevens, met ID-nummers die zullen worden gebruikt als zoekparameters.

66106 66107 66108 66109 66110 50127715 

Er zijn geen kolomnamen, geen andere gegevens. Dit zijn waarden waarnaar ik afzonderlijk wil zoeken in een ander bestand, een TSV. Ik heb ook een verkeerde uitspraak gedaan over de TSV-grootte, ik heb een TSV van 4 GB, die wordt gecomprimeerd tot 300 MB. Het bestand bevat meer vermeldingen dan al mijn programmas het zelfs kunnen bekijken. Hieronder ziet u een voorbeeld van een enkele vermelding uit een paar miljoen. IK MOET al deze gegevens in één keer ophalen, dus bijsnijden is geen optie.

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-methyl-2- (1-propylbutyl) – (6aR, 9aS) -3,4,5,8-tetrahydrocyclopenta [4,5] imidazo [2,1-b] purine-4- één :: 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 Calcium / calmoduline-afhankelijke 3″ , 5″ -cyclische nucleotide fosf odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Ik weet niet zeker hoe ik dit moet laten lezen als een TSV in dit vak, maar 50127715 is de eerste kolom, de ID-kolom. Ik wil dat mijn eerste CSV-bestand, dat de ID-nummers van belang bevat, het grote TSV-ID-nummer per keer in de eerste kolom doorzoekt. Als het nummer in de eerste kolom staat, wil ik dat het die regel naar een bestand schrijft en vervolgens naar de volgende ID zoekt. Ik wil alle resultaten in één bestand.

Ik “weet zeker dat er tijdens al mijn stappen om hier te komen, een gemakkelijkere manier is om dit te doen, maar ik weet duidelijk niet zeker hoe dit duidelijker. Ik wil dat het de grote TSV doorzoekt naar " 66106 " in kolom 1, en wanneer het de regel vindt om de hele regel in te schrijven een bestand. Zoek vervolgens naar " 66107 " en zodra het het heeft gevonden, wordt het aan hetzelfde bestand toegevoegd. Op deze manier heb ik een enkel bestand, kan een CSV of TSV zijn, met 1200 vermeldingen in plaats van enkele miljoenen.

Opmerkingen

  • Waarom niet gewoon ontleden de TSV rechtstreeks? awk -F '\t' scheidt invoervelden door middel van tabbladen. En inderdaad, standaard awk zal velden scheiden door aaneengesloten witruimte. Dus om alle mensen met blauwe ogen te krijgen (en de koptekst te behouden), heb je awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }' nodig.
  • Ik heb geprobeerd deze opdracht uit te voeren op een voorbeeldbestand met de naam " test.tsv ", met dezelfde invoer als hierboven vermeld, maar het produceerde een ongebruikelijke uitvoer. Het heeft zojuist alle oogkleuren vervangen door " Blauw " terwijl al het andere hetzelfde bleef.
  • $3 = "Blue" moet $3 == "Blue" zijn. De eerste is een opdracht, de laatste is een vergelijking.
  • Is dit een CSV of TSV?
  • De informatie over uw vereisten met een broodkruimel tegelijk verspreiden is niet ' een goede benadering om tot een goede oplossing te komen. bewerk uw vraag om een meer echt representatief voorbeeld te geven van wat u ' probeert te doen. Voeg een TSV-bestand, een CSV-bestand en de verwachte uitvoerbestanden toe die u verwacht als invoer. Zorg ervoor dat u al uw gebruiksscenarios bestrijkt, bijv. of alle overeenkomsten zijn tegen waarden in 1 kolom of verschillende overeenkomsten in verschillende kolommen, enz. Zie Hoe te vragen .

Antwoord

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

Het klinkt alsof je echt probeert te doen, een nieuwe bestand per ID dat, aangenomen dat de IDs uniek zijn zoals in uw voorbeeld, zou zijn:

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

of als u wilt dat elk uitvoerbestand de header bevat:

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

Reacties

  • Ik heb het voor de duidelijkheid bewerkt, maar ik wil eigenlijk maar 1 bestand met die namen. Omdat de gegevens enorm zijn, heb ik zojuist geprobeerd een voorbeeldset te maken voor demonstratiedoeleinden, maar ik ' ben nieuw bij programmeren, dus ik ' m niet zeker of ik ' m correct uitdruk wat ik nodig heb.

Antwoord

Voor iedereen die dit in de fu kan vinden tuurlijk, ik heb een oplossing. Het eerste dat ik deed, was de TSV naar een CSV converteren met:

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

Om vervolgens in mijn bestandscode te zoeken waarnaar ik op zoek was, is:

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

Hiermee wordt in de eerste kolom gezocht naar de tekst in een afzonderlijke CSV. In dit geval is " file1 " het bestand dat moet worden doorzocht en " file2 " bevat de strings waarnaar moet worden gezocht. Beide bestanden zijn in CSV-indeling.

Dit leverde een apart CSV-bestand op dat alle regels in bestand1 bevatte met een bepaalde ID in kolom 1 die overeenkomt met een van de IDs in bestand2.

Ik hoop dat dat helpt iemand ooit, want dit heeft mijn hersens al weken verwoest. Ik kreeg zelf de oplossing niet eens, mijn baas moest het me laten zien.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *