여러 값(예: str_pattern
)으로 변수를 설정한 다음 sed
명령의 값을 사용하여 범위를 이전 빈 줄이나 뒤로 일치시키려는 데 문제가 있습니다 ExecuteThread
.
- 샘플 스크립트 조각
str_pattern="String1 String2" tac $file | sed -n '/'"$str_pattern"'/,/^$/p' | tac
- 입력 파일 예
2023-01-01 01:00:00
--blank line --
ExecuteThread: #100 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.something
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
--blank line --
2023-01-01 02:00:00
ExecuteThread: #100 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.something
ExecuteThread: #102 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2
at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
--blank line --
- 원하는 출력
2023-01-01 01:00:00
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
2023-01-01 02:00:00
ExecuteThread: #102 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2
답변1
-00
Perl 에는 단락(하나 이상의 빈 줄로 구분)의 입력을 처리하고 여러 줄 문자열을 처리하기 위한 옵션( )이 있으므로 이를 달성하기 위해 Perl을 사용할 것입니다 .
Perl에는 -n
다음과 같이 작동하도록 하는 옵션이 있습니다 sed -n
(각 입력 행을 자동으로 인쇄하지 않고 입력을 읽고 처리)... 다음 sed -p
과 같이 작동하도록 sed
(읽기, 처리 및 자동으로 입력 인쇄)
$ perl -00 -n -e '
if (/String1|String2/) {
s/^.*StackTraceExample.*$//mg;
s/\n\n/\n/g;
print;
}' input.txt
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2
영어로:
현재 단락에 String1 또는 String 2가 포함된 경우 StackTraceExample(있는 경우)이 포함된 모든 줄을 삭제한 다음 StackTraceExample 줄을 삭제한 후 남아 있을 수 있는 추가 줄 바꿈을 삭제한 다음 수정된 단락을 인쇄합니다.
sh 또는 bash 스크립트에서 Perl로 String1, String2, ... StringN을 전달해야 하는 경우 한 가지 방법은 환경에서 내보낸 변수를 통해 전달하는 것입니다.
#!/bin/sh
str_pattern="String1|String2"
excl_pattern="StackTraceExample"
export str_pattern excl_pattern
perl -00 -n -e '
if (/$ENV{str_pattern}/) {
s/^.*(?:$ENV{excl_pattern}).*$//mg;
s/\n\n/\n/g;
print
}' input.txt
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2
str_pattern
및 의 값은 excl_pattern
고정 문자열이 아닌 Perl 정규식으로 해석되므로 리터럴로 처리하려는 특수 문자를 이스케이프 처리하세요.
%ENV
환경 변수에 대한 액세스를 제공하는 Perl의 해시(연관 배열)입니다.
참고: 불행하게도 bash 배열은 효과적으로 내보낼 수 없습니다( export
오류 코드는 반환되지 않지만 외부 프로그램 환경에서는 사용할 수 없습니다. 예를 들어 export foo=(1 2 3); declare -p foo ; env | grep ^foo=
bash에서 실행 하면 의 출력 에는 표시되지만 의 출력에는 foo
표시되지 않습니다). 이므로 변수는 스칼라 문자열이어야 합니다.declare
env
답변2
사용행복하다(이전 Perl_6)
fff
sed의 Raku 버전을 사용할 수 있습니다"트리거" 연산자.
다음은 시작하는 줄에서 캡처를 시작 \s* ExecuteThread
하고 빈 줄에서 캡처를 끝냅니다 [^^ $$]
( *.chars == 0
또한 OK). 필수 문자열 "String1" 및 "String2"를 문자 그대로 테스트합니다.
~$ raku -ne 'if m/ [^^ \s* ExecuteThread ] / fff / [^^ $$ ] / { .put if \
m/ | [^^ \s* ExecuteThread ]
| String1
| String2
| [^^ $$ ] / };' file
문제를 정리하려면 필요한 문자열을 다음과 같은 클래스 변수 로 추상화 String1
할 수 있습니다 .String2
regex
desired
~$ raku -ne 'my regex desired { String1 | String2 }; \
if m/ [^^ \s* ExecuteThread ] / fff / [^^ $$ ] / { .put if \
m/ | [^^ \s* ExecuteThread ]
| <desired>
| [^^ $$ ] / };' file
start
또한 동일한 추상화 트릭을 사용하면 stop
선언 및 정규식 클래스 변수를 사용하여 코드를 약간 무미건조하게 만들 수도 있습니다. 그래서 우리는 이 버전에 이르렀습니다.
~$ raku -ne 'my regex start { ^^ \s* ExecuteThread }; \
my regex stop { ^^ $$ }; \
my regex desired { String1 | String2 }; \
if (m/ <start> / fff / <stop> /) {
.put if m/ <start> | <desired> | <stop> / };' file
fff
초기 그룹화/선택 후에 는 더 간단한 접근 방식이 있을 수 있습니다.제거하다출력에 원하지 않는 줄이 있습니다(예: 마지막 절) {.put unless m/StackTraceExample/}
.
입력 예:
--blank line --
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
--blank line --
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2
at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
--blank line --
출력 예(위의 모든 코드 예):
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String1.line1
at com.stackify.stacktrace.String1.line2
ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
at com.stackify.stacktrace.String2.line1
at com.stackify.stacktrace.String2.line2