매우 긴 텍스트 파일이 있는데 파일 내용의 일부는 다음과 같습니다.
[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"},
위 텍스트 파일의 ID를 구문 분석 해야 하며 uniprot
예상 결과는 다음과 같습니다.
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
동일한 작업을 수행하기 위해 다음 명령을 시도했지만 아무것도 작동하지 않았습니다.
sed -e 's/"uniprot":"\(.*\)"},{"site":"/\1/' file.txt
cat file.txt | sed 's/.*"uniprot":" //' | sed 's/"site":".*$//'
위에서 언급한 ID를 분석하는 데 도움을 주세요.
미리 감사드립니다.
답변1
Linux 시스템을 사용하는 경우 다음을 매우 쉽게 수행할 수 있습니다.
$ grep -oP '"uniprot":"\K[^"]+' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
-o
각 줄 의 일치하는 부분만 인쇄 grep
하고 -P
Perl 호환 정규식을 활성화함을 나타냅니다. 정규식은 찾고 있지만 "uniprot":"
삭제합니다(즉, \K
"지금까지 일치하는 항목을 모두 삭제"하여 출력에 포함되지 않음을 의미함). 그런 다음 "
( ) 이 아닌 가장 긴 세그먼트를 찾습니다 [^"]+
.
물론 이는 JSON 데이터처럼 보이므로 더 복잡한 경우에는 적절한 구문 분석기를 사용해야 합니다 jq
. 예를 들어 종료 문을 추가하여 파일을 수정하고 ]
다음과 같이 만듭니다.
[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"}]
넌 할 수있어:
$ jq -r '.[].uniprot' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
답변2
자세히 살펴보면 입력 파일은 Python 데이터 구조입니다. 특히 사전 목록입니다. 닫는 대괄호를 추가해야 합니다.
ast 모듈을 통해 유효한 Python 데이터 구조인 문자열을 직렬화할 수 있습니다.
python3 -c 'import sys, ast
ifile,key = sys.argv[1:]
str = ""
with open(ifile) as fh:
for l in fh: str += l.rstrip()
lod = ast.literal_eval(str)
for d in lod: print(d[key])
' file uniprot
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
답변3
사용 gawk
:
awk 'BEGIN{RS=","}
/uniprot/{print gensub(/.*("uniprot":")(.*)".*/, "\\2", "g") }' input
이 명령에는 RS
쉼표로 설정된 레코드 구분 기호( )를 입력합니다.
그런 다음 gawk
내장 함수는 gensub()
backreference()를 사용하여 행을 원하는 패턴으로 바꿉니다 \\2
.
답변4
펄 5 솔루션
$ perl -nle 'print join"\n",m/uniprot\":\"(.*?)\"/g' file.txt
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
$