일치하는 패턴을 따르는 줄 부분만 반환(Unix)

일치하는 패턴을 따르는 줄 부분만 반환(Unix)

출력 파일이 있는 여러 하위 폴더(1,2,3....25)를 포함하는 상위 폴더(abeps)가 있으며 그 중 하나는 동일한 이름(opt.out)을 갖습니다. 이 파일에는 예측할 수 없는 출력이 있습니다. 다음은 필터링해야 하는 행의 예입니다.

A\HF=-1378.9118397\RMSD=4.560e-09\RMSF=1.758e-05\dipole=0.2110167,0.39

또는

978,3.8529967641,3.6669041122\version=ES64L-G09RevD.01\status=1-A\HF=-

그래서 질문은 \HF=에서 최대 \까지의 모든 것을 얻는 데 관심이 있다는 것입니다.

그러나 그들은 다른 라인에 있을 수 있고 심지어 HF도 다른 라인에 있을 수 있으므로 grep이 이를 포착하지 못합니다. 그런 다음 결과를 파일에 쓰려고 합니다.

grep 'HF=-' abeps/*/opt.out > data

결과적으로 이런게 나왔네요

abeps/10/opt.out: 1-A\HF=-1378.9114895\RMSD=5.126e-09\RMSF=5.036

abeps/12/opt.out: \State=1-A\HF=-1378.9185518\RMSD=2.940e-09\RMSF

abeps/13/opt.out: 33413\version=ES64L-G09RevD.01\status=1-A\HF=-137

답변1

귀하의 grep 버전이 PCRE(Perl Compatible Regular Expressions)를 지원하는 경우 Perl의 뒤돌아보기 및 미리보기 기능을 사용할 수 있습니다.

grep -oPz '(?<=\\HF=)(.|\n)+?(?=\\)'

또는 pcregrep(있는 경우) 와 함께

pcregrep -Mo '(?<=\\HF=)(.|\n)+?(?=\\)'

관심 있는 패턴이 실제로 줄 분할인 경우 반환된 텍스트에 줄 바꿈이 유지된다는 점을 명심하세요. tr결과를 사용할 때나 사용하기 전에 이를 제거하는 것이 좋습니다.sed

텍스트 자체를 줄로 나눌 수 없는 경우( \HF및 태그만) 더 간단한 줄로 바꿀 \수 있습니다.(.|\n)+?.+?

grep -oPz '(?<=\\HF=).+?(?=\\)'

\HF=원래 게시물에 대한 귀하의 의견에서 알 수 있듯이 어느 시점에서든 토큰이 줄 바꿈으로 분할될 수 있는 경우 PCRE는 현재 가변 길이 뒤돌아보기를 지원하지 않으므로 약간 다른 접근 방식이 필요합니다. 이 경우 시도해 볼 수 있습니다

grep -oPz '\\\n?H\n?F\n?=\K(.|\n)+?(?=\\)'

여기서 Lookbehind는 다음을 사용하여 의사 앵커 표현식으로 대체됩니다.\K

답변2

당신은 또한 사용할 수 있습니다 sed,

sed -r '/.*HF=([^\]*)\\?.*/s//\1/g' file

예:

$ echo 'A\HF=-1378.9118397\RMSD=4.560e-09\RMSF=1.758e-05\Dipole=0.2110167,0.39' | sed -r '/.*HF=([^\]*)\\?.*/s//\1/g'
-1378.9118397

$ echo '978,3.8529967641,3.6669041122\Version=ES64L-G09RevD.01\State=1-A\HF=-' | sed -r '/.*HF=([^\]*)\\?.*/s//\1/g'
-

답변3

최근의 pcregrep:

pcregrep -Mo1 '(?s)\\HF=(.*?)\\'

관련 정보