다음과 같은 표준 csv 파일이 아닌 쉼표로 구분된 파일이 있습니다.
XYZ,143,ABC/genomes/date/pa341,dog,available
567,FTR/genomes/date/ha76870,horse,waiting
214,GEN/genomes/date/btr256,N/A,avialable,stored
...
"/genomes"로 시작하여 다음 쉼표 "," 문자까지 모든 문자열을 추출하고 싶습니다. 예상되는 출력은 다음과 같습니다.
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256
다음을 시도했지만 필요하지 않은 추가 정보가 인쇄됩니다.
grep -o '/genomes.*,' myfile.txt
output:
/genomes/date/pa341,dog,
/genomes/date/ha76870,horse,
/genomes/date/btr256,N/A,stored
답변1
*
"가능한 가장 긴 문자열과 일치"를 의미하기 때문에 방법이 실패합니다 . 이것을 "탐욕스러운" 수정자라고 합니다. 탐욕스럽지 않은 연산자인 "가능한 가장 짧은 문자열과 일치"를 원합니다. 따라서 지원하는 경우 다음을 사용하여 확장 정규식을 grep
활성화 하고 실행하십시오.-P
$ grep -Po '/genomes.*?,' file
/genomes/date/pa341,
/genomes/date/ha76870,
/genomes/date/btr256,
그러나 더 나은 접근 방식은 ,
문자가 아닌 문자를 최대한 많이 일치시키는 것입니다.
$ grep -o '/genomes[^,]*' file
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256
답변2
정보를 얻는 몇 가지 방법은 다음과 같습니다.
$ grep -oP '/genomes((?!,).)*' myfile.txt
$ perl -F, -pale '
shift @F until $F[0] =~ m{/genomes.*};
$_ = $&;
' myfile.txt
$ perl -lne '
my $p1 = index $_, "/genomes";
my $p2 = index $_, ",", $p1;
print substr $_, $p1, $p2-$p1;
' myfile.txt
$ sed -ne '
/\n/!s|/genomes|\n&|
y/,/\n/
/^\/genomes/!D;P
' myfile.txt
결과:
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256