명령줄: grep을 사용하여 줄의 일부만 가져옵니다.

명령줄: grep을 사용하여 줄의 일부만 가져옵니다.

다음과 같은 줄이 포함된 파일이 있습니다.

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를 사용하여 이 작업을 수행할 수 있습니다 .treetrain

$ grep -oP 'train\ttree\t.*leaf_id "\K[^"]+' file
ENSG00000223972

make는 줄에서 일치하는 부분 -o만 인쇄하고 Perl 호환 정규식을 활성화하여 및 를 제공합니다 .grep-P+\K

정규식은 , traina \t, \treeanother \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세 번째 필드가 이면 tree9번째 필드가 확인되고 큰따옴표 안의 문자열이 인쇄됩니다.

후자는 다음을 사용하여 (잘못) 달성됩니다 split(). 필드는 각 큰따옴표로 분할되고 모든 부분은 배열 변수에 저장됩니다 f. 두 번째 항목 f[2]( awk배열대개1)로 시작하는 것은 따옴표 안의 문자열이며 인쇄됩니다(첫 번째 항목 fleaf_id, 세 번째 항목은 ; root_id등).

답변3

sed를 사용하세요:

$ sed -nE 's/^.*train.*tree.*leaf_id "([A-Z][A-Z0-9]*)";.*$/\1/p' file
ENSG00000223972

관련 정보