다음과 같은 줄이 포함된 파일이 있습니다.
1 train tree 11869 12227 . + . leaf_id "ENSG00000223972"; root_id "ENST00000456328";
내가 검색하는 행은 train
두 번째와 tree
세 번째 열에 있어야 합니다.
leaf_id
따옴표로 시작하는 콘텐츠 만 가져오고 싶습니다 . 나머지 줄은 관련이 없습니다. 나는 정규 표현식을 사용하여 그룹을 캡처하려고 시도했지만 성공하지 못했습니다.ABC
공백이 아닌 공백으로 열을 구분하세요 \t
. 마지막 필드는 leaf_id "ENSG00000223972"; root_id "ENST00000456328";
항목이 탭이 아닌 공백으로 구분되는 필드입니다.
감사해요
답변1
문자열과 문자열 이 두 번째와 세 번째 필드에 각각 나타나고 다른 곳에서는 나타나지 않는 한 grep
실제로 GNU를 사용하여 이 작업을 수행할 수 있습니다 .tree
train
$ grep -oP 'train\ttree\t.*leaf_id "\K[^"]+' file
ENSG00000223972
make는 줄에서 일치하는 부분 -o
만 인쇄하고 Perl 호환 정규식을 활성화하여 및 를 제공합니다 .grep
-P
+
\K
정규식은 , train
a \t
, \tree
another \t
, 그 다음 무엇이든 찾을 때까지 검색합니다 leaf_id "
. 그런 다음 지금까지 일치시켰던 모든 것을 잊어버리 \K
라고 하세요 . grep
따라서 이제 우리는 이 이후에 가장 긴 비문자 세그먼트를 찾습니다 "
. 이것이 여러분이 찾고 있는 유전자 이름이 될 것입니다.
일치 tree
하고 train
올바른 열에만 있으려면 다음을 수행하면 됩니다.
$ awk -F'\t' '$2=="train" && $3=="tree"' file | grep -oP 'leaf_id "\K[^"]+'
ENSG00000223972
또는:
$ perl -F'\t' -lane 'if($F[1] eq "train" && $F[2] eq "tree" && $F[8]=~/leaf_id\s+"\K([^"]+)/){print $1}' file
ENSG00000223972
답변2
awk
이 작업 에 사용할 수 있습니다 . 파일이 호출되었다고 가정하면 input.tsv
관련 명령은 다음과 같습니다.
awk -F"\t" '$2=="train" && $3=="tree" {split($9,f,"\""); print f[2]}' input.tsv
-F"\t"
이렇게 하면 각 탭( )의 행이 별도의 필드로 분할 됩니다 . 두 번째 필드가 이고 train
세 번째 필드가 이면 tree
9번째 필드가 확인되고 큰따옴표 안의 문자열이 인쇄됩니다.
후자는 다음을 사용하여 (잘못) 달성됩니다 split()
. 필드는 각 큰따옴표로 분할되고 모든 부분은 배열 변수에 저장됩니다 f
. 두 번째 항목 f[2]
( awk
배열대개1)로 시작하는 것은 따옴표 안의 문자열이며 인쇄됩니다(첫 번째 항목 f
은 leaf_id
, 세 번째 항목은 ; root_id
등).
답변3
sed를 사용하세요:
$ sed -nE 's/^.*train.*tree.*leaf_id "([A-Z][A-Z0-9]*)";.*$/\1/p' file
ENSG00000223972