
반복되는 특성 목록인 로그 파일이 있습니다. 예를 들어:
## This is the pattern of lines
time
urgency
icon_path
summary
body
appname
## Below is what the log file would actually look like
12:30
critical
test notification
notification
notify-send
11:00
low
earlier notification
notification
notify-send
10:46
normal
hello
world
dunstify
내 검색어와 일치하는 줄 블록/클러스터를 검색한 다음 bash에서 삭제하는 방법을 찾으려고 합니다. 위의 예에서 볼 수 있듯이 줄이 비어 있는 경우도 있고 채워지는 경우도 있습니다. 지금까지 내가 찾은 최고의 "솔루션"은 sed '/12:30/,+5 d'
or 약간 더 나은 sed '/12:30/,/notify-send/d'
. 이 두 가지 모두의 문제점은 첫 번째 항목이 타임스탬프의 모든 항목을 삭제하여 둘 이상의 로그 항목을 삭제한다는 것입니다. 다른 명령의 문제점은 동일한 시간과 appname을 가진 항목이 두 개 이상 있으면 일치하는 모든 항목이 삭제된다는 것입니다.
내가 일하려고 노력했지만 눈에 띄게 실패했던 것은 다음과 같은 일을 하는 것입니다 sed '/12:30\n^.*$\n^.*$\ntest notification\nnotification\nnotify-send/d' /tmp/notification_log
. 두 번째와 세 번째 줄은 무엇이든 될 수 있습니다(각각 긴급 및 icon_path 줄). 이것이 제가 사용한 이유입니다 ^.*$
(솔직히 말해서 이것이 적절한 정규식인지 확실하지 않습니다).
편집: 위의 실패한 명령을 사용하면 다음과 같은 결과가 나올 것으로 예상됩니다.
11:00
low
earlier notification
notification
notify-send
10:46
normal
hello
world
dunstify
해당 명령에는 다음이 입력되었습니다.
12:30
*anything*
*anything*
test notification
notification
notify-send
답변1
모든 클러스터가 M 줄 길이이고 M이 고정되어 있고 클러스터가 겹치지 않고 클러스터의 시작 부분을 검색할 필요가 없다면 실제로 그렇게 어렵지는 않습니다. 우리의 경우 M은 6입니다.
sed
여러 줄을 일치시킬 수 있지만 일반적으로 한 번에 한 줄씩 처리하므로 패턴 공간에 추가 줄을 명시적으로 추가해야 합니다. 당신은 그것을 수행합니다 N
:
sed 'N;N;N;N;N; /12:30\n.*\n.*\ntest notification\nnotification\nnotify-send/d'
^
나머지는 앵커 가 없는 코드입니다 $
. 앵커는 종종 각각 "줄의 시작" 및 "줄의 끝"과 연관됩니다. 하지만 sed
실제로는 "… 문자열"입니다. 한 번에 한 줄씩 처리 하면 sed
차이가 없습니다. 우리의 경우 앵커는 "… 문자열"이라는 것을 확실히 기억해야 합니다. 중간에 놓는 것은 의미가 없습니다. 결코 어떤 것과도 일치하지 않을 것입니다. sed
애초에 그것들을 앵커로 해석하지 않고 문자 그대로 해석할 것 ^
입니다 $
.
문자열 중간에 "... of the line" 앵커가 필요하지 않습니다. 마지막 줄을 제외한 모든 줄은 개행 문자 바로 앞에서 끝납니다. 모든 줄은 개행 문자 바로 다음에 시작됩니다. 그러니 충분히 일치합니다 \n
.
.*
아마도 앵커를 사용하여 (탐욕스럽고 개행 문자와 일치할 수 있음) 둘 이상의 행과 일치하지 않는지 확인하려고 시도했을 수도 있습니다 . "… 라인의" 앵커 역할을 한다고 ^
해도 여전히 욕심이 많을 것입니다. 이것을 고려하십시오: 패턴 공간은 마지막 라인* 뒤에 개행 문자를 포함하지 않습니다. 우리의 경우에는 패턴 공간에 최대 6개의 라인이 있다는 것을 알고 있습니다. 정확히 5번 사용했습니다 . 이는 정규식의 각 조각이 클러스터의 특정 줄에만 일치할 수 있음을 보장합니다.$
.*
sed
\n
스틸 앵커가 도움이 될 수 있습니다. 위 명령은 로 끝나는 클러스터를 삭제할 수 있습니다 notify-send-whatever
. $
이를 방지하는 올바른 방법입니다. 12:30
일치하는 시간 외에는 시간이 없습니다 12:30
. 하지만 의 경우에는 다르 2:30
므로 일반적으로 ^
유용할 수도 있습니다. 향상된 명령:
sed 'N;N;N;N;N; /^12:30\n.*\n.*\ntest notification\nnotification\nnotify-send$/d'
* 이는 패턴 공간 끝에 개행 문자가 절대 있을 수 없다는 의미는 아닙니다. 끝에 있는 개행 문자는 해당 문자 바로 뒤에 행이 있음을 나타냅니다. 마지막 줄이고 비어 있습니다. 그리고 그 뒤에는 줄바꿈 문자가 없으므로 "마지막 줄 뒤에는 줄바꿈 문자가 없습니다"가 나타납니다.