awk를 통해 CSV 데이터 작업

awk를 통해 CSV 데이터 작업

CSV 파일에서 개별 데이터를 가져와서 grep 또는 awk 명령에서 변수로 사용하는 방법을 찾으려고 합니다. 둘 다 적절해 보이지만 이 작업을 적절하게 수행하도록 지시하는 방법을 잘 모르겠습니다.

예를 들어 아래와 같이 TSV 형식의 데이터 세트가 있습니다.

ID    Name    Eye Color 

1     Bill    Blue 
2     Sam     Blue 
3     Fred    Brown 
4     Joe     Brown 
5     Ted     Blue 
6     Bob     Brown

이는 실제 데이터 세트는 아니지만 동일한 방식으로 동작합니다. 이것은 전체 단백질 결합 데이터베이스입니다. TSV는 300MB이고 수백만 개의 항목과 수십 개의 열을 포함하므로 실제 내용을 명확하게 포함할 수 없습니다.

파란 눈을 가진 개인의 행을 포함하는 파일을 만들고 싶었기 때문에 "ID" 열로 구성된 CSV 파일을 만들었습니다. 이 경우에는 다음과 같습니다.

1, 2, 5

"ID"가 포함된 이 CSV는 "Grep" 명령을 사용하여 키워드를 검색하여 생성되었습니다.

나는 궁극적으로 다음과 같은 TSV 파일을 원합니다. 1 Bill Blue 2 Sam Blue 5 Ted Blue

하지만 어떻게 해야 할지 모르겠습니다. awk 또는 grep을 사용하여 각 항목에 대해 개별적으로 생성하고 ID 번호를 조건으로 포함할 수 있지만, 제가 사용하는 CSV에는 1200개의 항목이 있으므로 이 프로세스를 자동화하고 싶습니다.

아래 코드는 단일 항목에 대해 원하는 결과를 생성하지만 ID 번호를 사용하여 검색을 자동화하고 싶습니다.

BindindDB_All.tsv는 내 소스 파일이며 수백만 개의 항목이 있습니다. 그러면 "new.tsv"라는 TSV가 생성되고 ID(열 1)가 66106인 BininddDB_All.tsv 파일의 전체 행이 포함됩니다.

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

나는 이런 일을하고 싶다 :

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

각 ID를 읽고 행을 new.csv에 인쇄한 후 다음 ID를 읽고 동일한 작업을 수행합니다.

CSV 파일에는 각각 고유 ID가 있는 수백만 개의 검색어와 비교할 수 있는 1,200개의 검색어가 포함되어 있습니다. 각 행의 다른 변수에서 ID를 찾으므로 열 1만 검색해야 합니다.

요약하자면, 행의 열 1을 보고 이를 CSV 파일의 첫 번째 숫자와 비교하여 일치하는지 확인해야 합니다. 일치하는 항목이 없으면 1열의 다음 행을 확인해야 하며, 일치하는 항목을 찾을 때까지 계속 확인해야 합니다. 열 1이 CSV의 첫 번째 데이터 요소와 일치하는 행을 찾으면 해당 행을 출력하고 싶습니다. 그런 다음 1200개의 행을 모두 찾을 때까지 CSV의 두 번째 항목에 대해 반복하고 싶습니다.

어떤 아이디어가 있나요? 이것은 루프 문제처럼 들리지만 작동시키는 방법도 모르겠습니다.

편집하다:

사람들이 여전히 도움을 주려고 하는 것 같으니 게시된 질문에 답변해 보겠습니다.

다음은 검색 매개변수로 사용될 ID 번호가 포함된 실제 데이터의 처음 6개 항목입니다.

66106     
66107    
66108    
66109     
66110    
50127715    

열 이름도 없고 다른 데이터도 없습니다. 서로 다른 파일(TSV)에서 개별적으로 검색하고 싶은 값들입니다. TSV 크기에 관해서도 저도 틀렸습니다. 300MB 압축된 4GB TSV가 있습니다. 파일에는 내 프로그램에서 볼 수 있는 것보다 더 많은 항목이 포함되어 있습니다. 다음은 수백만 개의 항목 중 단일 항목의 예입니다. 이 모든 데이터를 한 번에 추출해야 하므로 정리할 수 없습니다.

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 CSRSQFSFDXYRFV-OLZOCXBDSA-N 50073697 5-메틸-2-(1-프로필부틸)-(6aR,9aS )-3, 4,5,8-테트라하이드로사이클로펜타[4,5]이미다조[2,1-b]퓨린-4-온::CHEMBL280307 포스포디에스테라제 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, Schering-Plough 연구소 http://www.bind/chemsearch/marvin/MolStructure.jsp?monomerid=50073697 http://www.binddb.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.bounddb.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 LAY PEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILY NDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTM SLILHAAD ISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQ QNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS 칼슘/칼모듈린 의존성 3',5'-고리형 뉴클레오티드 포스포디에스테라제 1A P141 00 Q08E30,Q28063

이 상자에서 TSV로 어떻게 읽어야할지 모르겠지만 50127715가 첫 번째 열인 ID 열입니다. 관심 있는 ID 번호가 포함된 초기 CSV 파일에서 한 번에 하나의 ID 번호씩 첫 번째 열에서 큰 TSV를 검색하도록 하고 싶습니다. 숫자가 첫 번째 열에 포함되어 있으면 해당 행을 파일에 쓴 후 다음 ID를 검색하고 싶습니다. 모든 결과를 하나의 파일에 저장하고 싶습니다.

여기까지 오기 위해 취한 모든 단계에서 이 작업을 수행하는 더 쉬운 방법이 있다고 확신하지만 이를 더 명확하게 만드는 방법은 확실하지 않습니다. 열 1의 큰 TSV에서 "66106"을 검색하고 해당 행을 찾으면 전체 행을 파일에 쓰도록 하고 싶습니다. 그런 다음 "66107"을 검색하여 찾은 후 동일한 파일에 추가하십시오. 이렇게 하면 수백만 개가 아닌 1,200개의 항목이 포함된 CSV 또는 TSV 파일을 갖게 됩니다.

답변1

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

그러나 실제로 원하는 것은 각 ID에 대해 새 파일을 만드는 것 같습니다. 예에서와 같이 ID가 고유하다고 가정하면 다음과 같습니다.

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

또는 각 출력 파일에 헤더를 포함시키려는 경우:

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

답변2

나중에 이 문제를 발견할 수 있는 사람을 위해 해결책이 있습니다. 내가 한 첫 번째 일은 다음 명령을 사용하여 TSV를 CSV로 변환하는 것입니다.

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

그러면 내가 찾고 있는 파일을 검색하는 코드는 다음과 같습니다.

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

그러면 별도의 CSV에 포함된 텍스트의 첫 번째 열을 검색합니다. 이 예에서 "file1"은 검색할 파일이고 "file2"에는 검색할 문자열이 포함되어 있습니다. 두 파일 모두 CSV 형식입니다.

그러면 file2에 포함된 ID 중 하나와 일치하는 열 1의 특정 ID가 있는 file1의 모든 행을 포함하는 별도의 CSV 파일이 생성됩니다.

이것이 몇 주 동안 내 두뇌를 죽였기 때문에 언젠가 누군가에게 도움이 되기를 바랍니다. 나 스스로 해결책을 찾지도 못했고, 상사가 나에게 보여줘야만 했다.

관련 정보