다음 줄이 포함된 파일이 있습니다.
.......... FROM ABCD_EXT
.......... FROM HEG_EXT1
.......... from
xyz_EXT
.......... FROM abd_EXT2
..........where QWT_EXT.SID=POI_EXT.GET
..........where QWT_EXT.SID=POI_GET.END_EXT
"FROM"(대소문자 구분 안 함) 옆이나 아래에 있고 _EXT로 끝나는 단어를 grep하면 됩니다.
즉, 예상되는 출력은 다음과 같습니다.
ABCD_EXT
xyz_EXT
편집: 예, 같은 줄에 나타나든 다음 줄에 나타나든 'from' 뒤의 다음 단어를 grep해야 합니다.
나는 이것을 시도했고 첫 번째 부분을 올바르게 얻었습니다(같은 줄).
grep _EXT rt.sql |grep -i from|sed -e 's/_EXT/_EXT /g'|awk '{print $NF}'|grep _EXT
아래 줄에서 단어를 얻는 것이 문제입니다.
답변1
그리고 pcregrep
:
pcregrep -Mo1 '(?<!\S)(?i:from)\s+(\S*_EXT)(?!\S)' < rt.sql
-M
M
여러 줄 모드 의 경우-o1
첫 번째o
캡처 그룹 과 일치하는 콘텐츠를 출력합니다 .1
\s
공백 문자(적어도 공백, 탭, CR 및 LF 포함)와 일치하고\S
공백이 아닌 문자와 일치합니다.x+
: 1개 이상의x
s 와 일치x*
: 0개 이상의x
s와 일치합니다.(?i:from)
:from
, 대소문자를 구분하지 않으며 와 동일합니다[fF][rR][oO][mM]
.(?<!\S)
: 공백이 아닌 경우 또는 IOW에 대한 부정적인 뒤돌아보기전제는 이전 내용이 비어 있지 않다는 것입니다.(공백이나 주제의 시작 부분에도 동일하게 적용됩니다).(?!\S)
: 똑같지만 뒤가 아니라 앞을 바라봅니다. SQL이라면;
허용하고 싶을 수도 있습니다.(?![^\s;])
해당 항목이 없으면 pcregrep
( 의 첫 번째 항목 perl
)을 사용하여 전체 파일을 연기할 수 있습니다.p
pcregrep
-0777
perl -l -0777 -ne 'print for /(?<!\S)(?i:from)\s+(\S*EXT)(?!\S)/g' < rt.sql
또는 GNU를 사용하여 grep
PCRE 지원으로 구축된 경우(이것은 -P
일치를 위해 Perl과 같은 정규식을 사용하는 옵션을 추가합니다):
grep -zPo '(?<!\S)(?i:from)\s+\K\S*EXT(?!\S)' < rt.sql | tr '\0' '\n'
GNU는 첫 번째 캡처 그룹 일치 항목 의 인쇄를 grep
지원하지 않기 때문에 대신 일치 항목의 전체 내용을 인쇄하지만 일치 항목으로 무엇을 eep할지를 매처에게 알려줍니다 .-o<n>
n
-o
\K
K
행이 아닌 NUL로 구분된 레코드를 처리 하므로 -z
입력에 NUL이 포함되어 있지 않다고 가정하면(일반적으로 SQL 및 텍스트의 경우에 해당해야 함) 이는 파일의 전체 내용을 구성하는 하나의 레코드일 것입니다. Perl에서와 같이 위의 후루룩 패턴입니다. 그러나 출력 레코드 구분 기호도 NUL이므로 tr
각 일치 항목이 별도의 줄에 있도록 이를 줄 바꿈으로 변환해야 합니다.
답변2
GNU 사용sed
$ sed -En 'N;s/.*from( ([^_]*_ext\>)[^\n]*\n.*|\n.* ([[:alpha:]]+_ext\>))/\2\3/Ip' input_file
ABCD_EXT
xyz_EXT
답변3
샘플 데이터로 시도해 보세요 datafile
.
> awk -v printfirst=0 'BEGIN {IGNORECASE=1}
{if (printfirst == 1) {
print $1; printfirst=0; next
}
}
{for (i=1;i<=NF;i++)
if ($i ~ /^from$/) {
if (i == NF) {printfirst=1}
else if ($(i+1) ~ /_EXT$/) {print $(i+1)}
}
}' datafile
ABCD_EXT
xyz_EXT
> _
이를 수행하는 방법에는 여러 가지가 있습니다 awk
(여기 Awk의 GNU 버전이 있습니다). 나는 편의를 위해 그리고 입력 파일을 두 번 구문 분석하는 것을 피하기 위해 이것을 선택했습니다.
-v
Awk에 변수를 전달하기 위한 플래그입니다. 변수를printfirst
0으로 초기화하고,BEGIN {IGNORECASE=1}
Awk 검색 패턴에서 대소문자를 구분하지 않도록 설정- 첫 번째
{}
블록: 첫 번째 Awk 필드를 조건부로 인쇄합니다. 즉, 레코드$1
로 점프합니다.next
- 두 번째 블록
{}
: 구문 분석된 레코드from
의 경우 대소문자를 구분하지 않고 각 필드를 일치시키려고 합니다.- 일치하는 항목이 없으면 아무 작업도 수행하지 않습니다.
- 일치하는 경우:
- 일치하는 필드가 레코드의 마지막 필드인 경우 awk 내부 변수를
printfirst
1로 설정하고 다음 레코드로 이동합니다. - 일치하는 필드가 레코드의 마지막 필드가 아닌 경우 레코드의 다음 필드를 인쇄합니다.
- 일치하는 필드가 레코드의 마지막 필드인 경우 awk 내부 변수를