Używanie danych CSV z awk

Próbuję znaleźć sposób na pobranie poszczególnych danych z pliku CSV i użycie ich jako zmiennej w pliku grep lub awk polecenie. Każda z tych opcji wydaje się odpowiednia, ale nie wiem, jak to zrobić.

Na przykład mam zbiór danych w formacie TSV, który wygląda następująco:

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

To nie jest rzeczywisty zestaw danych, ale zachowuje się w ten sam sposób. To jest cała baza danych powiązań białek, TSV ma 300 MB z milionami wpisów i dziesiątkami kolumn, więc nie mogę” t czysto ” zawierać prawdziwe rzeczy.

Chcę utworzyć plik zawierający wiersze z osobami z niebieskimi oczami, dlatego utworzyłem plik CSV składający się z " ID ", która w tym przypadku wyglądałaby następująco:

1, 2, 5

Ten plik CSV zawierający " Identyfikator " został wygenerowany przy użyciu " Grep " polecenie wyszukania hasła kluczowego.

Ostatecznie chcę plik TSV, który wygląda następująco: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Ale nie wydaje mi się wymyślić jak to zrobić. Mogę go stworzyć indywidualnie dla każdego wpisu używając awk lub grep i włączając numer ID jako kryterium, jednakże CSV, którego używam ma 1200 wpisów, więc chciałbym zautomatyzować ten proces.

Poniżej znajduje się kod który da pożądany wynik dla pojedynczego wpisu, ale chcę użyć numerów ID do automatycznego wyszukiwania.

BindindDB_All.tsv jest moim plikiem źródłowym z kilkoma milionami wpisów. Spowoduje to utworzenie TSV o nazwie " new.tsv " i zawiera cały wiersz pliku BindindDB_All.tsv, gdzie identyfikator (w kolumnie 1) jest równy 66106.

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

Chciałbym zrobić coś takiego:

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

gdzie przeczytałbym każdy identyfikator, wydrukuj wiersz do nowego.csv, a następnie przeczytaj następny identyfikator i zrób to samo.

Plik CSV zawiera 1200 wyszukiwanych haseł, które można porównać z kilkoma milionami możliwości, z których każdy ma unikalny identyfikator. potrzebuje go TYLKO do wyszukiwania w kolumnie 1, ponieważ znajdzie identyfikator w innej zmiennej es w każdym wierszu.

Podsumowując, muszę spojrzeć na pierwszą kolumnę wiersza, porównać z pierwszą liczbą w moim pliku CSV i sprawdzić, czy pasuje. Jeśli nie pasuje, musi sprawdzić następny wiersz w kolumnie 1 i tak dalej, aż znajdzie dopasowanie. Kiedy znajdzie wiersz, w którym kolumna 1 pasuje do pierwszego punktu danych CSV, chcę, aby wypisał wiersz. Następnie chcę, aby powtórzył się dla drugiego wpisu w pliku CSV, aż znajdzie wszystkie 1200 wierszy.

Jakieś pomysły? Brzmi to jak problem z pętlą, ale ja też nie wiem, jak to zrobić.

EDYCJA:

Ponieważ ludzie nadal wydają się chętni do pomocy, spróbuję odpowiedzieć na pytania które zostały wysłane.

Oto pierwszych 6 wpisów moich prawdziwych danych, zawierających numery identyfikacyjne, które będą używane jako parametry wyszukiwania.

66106 66107 66108 66109 66110 50127715 

Nie ma nazw kolumn, żadnych innych danych. Są to wartości, których chcę szukać indywidualnie w innym pliku, TSV. Również źle napisałem co do rozmiaru TSV, mam 4 GB TSV, który kompresuje do 300 MB. Plik zawiera więcej wpisów, niż pozwala na to którykolwiek z moich programów. Poniżej znajduje się przykład pojedynczego wpisu z kilku milionów. POTRZEBUJĘ pobrać wszystkie te dane naraz, więc ich przycinanie nie jest opcja.

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 / h 11-13H, 4-10H2,1-3H3, (H, 20,21) / t12-, 13 + / m1 / s1 CSRSQF SFDXYRFV-OLZOCXBDSA-N 50073697 5-metylo-2- (1-propylobutylo) – (6aR, 9aS) -3,4,5,8-tetrahydrocyklopenta [4,5] imidazo [2,1-b] puryn-4- one :: CHEMBL280307 Fosfodiesteraza 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-Plow 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 wapnia / kalmoduliny zależny 3″ , 5″ -cykliczny nukleotyd fosforu odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Nie jestem pewien, jak to odczytać jako TSV w tym polu, ale 50127715 to pierwsza kolumna, kolumna ID. Chcę, aby mój początkowy plik CSV, zawierający interesujące numery identyfikacyjne, przeszukiwał duży TSV po jednym numerze identyfikacyjnym w pierwszej kolumnie. Jeśli liczba jest zawarta w pierwszej kolumnie, chcę, aby zapisała tę linię do pliku, a następnie wyszukała następny identyfikator. Chcę otrzymać wszystkie wyniki w jednym pliku.

Jestem pewien, że przez wszystkie moje kroki, aby to osiągnąć, jest łatwiejszy sposób, ale najwyraźniej nie jestem pewien, jak to zrobić to jaśniejsze. Chcę, aby przeszukał duży TSV pod kątem " 66106 " w kolumnie 1, a gdy znajdzie wiersz, w którym ma zostać zapisany cały wiersz plik. Następnie wyszukaj " 66107 " i po znalezieniu doda go do tego samego pliku. W ten sposób mam pojedynczy plik, może być CSV lub TSV, zawierający 1200 wpisów zamiast kilku milionów.

Komentarze

  • Dlaczego nie po prostu przeanalizować TSV bezpośrednio? awk -F '\t' oddzieli pola wejściowe tabulatorami. I rzeczywiście, domyślnie awk oddziela pola ciągłymi białymi znakami. Aby uzyskać wszystkie niebieskookie osoby (i zachować nagłówek), potrzebujesz tylko awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Próbowałem uruchomić to polecenie na przykładowym pliku o nazwie " test.tsv ", z tymi samymi danymi wejściowymi, co wymienione powyżej, ale dały nietypowe dane wyjściowe. Po prostu zastąpiono wszystkie kolory oczu " niebieskim ", podczas gdy wszystko inne pozostało takie samo.
  • $3 = "Blue" powinno być $3 == "Blue". To pierwsze to zadanie, drugie to porównanie.
  • Czy to plik CSV czy TSV?
  • Wydzielanie informacji o Twoich wymaganiach na raz nie jest ' to dobre podejście do uzyskania dobrego rozwiązania. edytuj swoje pytanie, aby przedstawić bardziej reprezentatywny przykład tego, co ' próbujesz zrobić. Dołącz plik TSV, plik CSV i oczekiwane pliki wyjściowe, których oczekujesz, biorąc pod uwagę to jako dane wejściowe. Upewnij się, że uwzględnisz wszystkie przypadki użycia, np. czy wszystkie dopasowania dotyczą wartości w 1 kolumnie, czy różne dopasowania w różnych kolumnach itp. Zobacz Jak zapytać .

Odpowiedź

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

Wygląda na to, że naprawdę próbujesz zrobić, to stworzyć nowy plik na identyfikator, który przy założeniu, że identyfikatory są unikalne, jak w przykładzie, będzie wyglądał następująco:

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

lub jeśli chcesz, aby każdy plik wyjściowy zawierał nagłówek:

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

Komentarze

  • Zmodyfikowałem go dla większej przejrzystości, ale naprawdę chcę tylko 1 plik zawierający te nazwy. Ze względu na ogrom danych, po prostu próbowałem stworzyć przykładowy zestaw do celów demonstracyjnych, ale ' jestem nowy w programowaniu, więc ' Nie jestem pewien, czy ' prawidłowo wyrażam to, czego potrzebuję.

Odpowiedź

Dla każdego, kto może znaleźć to w fu tura, mam rozwiązanie. Pierwszą rzeczą, jaką zrobiłem, było przekonwertowanie TSV na CSV za pomocą:

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

Następnie, aby wyszukać mój kod pliku, którego szukałem, było:

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

Spowoduje to przeszukanie pierwszej kolumny pod kątem tekstu zawartego w oddzielnym pliku CSV. W tym przypadku " plik1 " to plik do przeszukania, a " plik2 " zawiera ciągi do wyszukania. Oba te pliki mają format CSV.

Stworzyło to oddzielny plik CSV, który zawierał wszystkie wiersze w pliku1, który miał pewien identyfikator w kolumnie 1, który pasuje do jednego z identyfikatorów zawartych w pliku2.

Mam nadzieję, że to pomoże Ktoś kiedyś, bo to mnie szarpało tygodniami. Nawet nie dostałem rozwiązania, mój szef musiał mi je pokazać.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *