저는 CentOS 7에서 작업 중이며 find/sed oneliner를 사용하여 많은 수의 파일을 복구하려고 합니다. 구체적으로 말하면, 연속으로 두 개가 있습니다.
[monitor://...]
먼저 각 (작업) 바로 뒤에 "ignoreOlderThan = 14d"를 추가합니다.- 둘째,
[monitor://...]
두 개의 "ignoreOlderThan"이 있는 그룹을 찾아 마지막 항목을 삭제합니다.
다음과 유사한 파일이 수백 개 있습니다(이것이 제가 사용하고 있는 현재 테스트 파일입니다).
[default]
host = 10.2.2.15
[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d
[monitor://truck]
ignoreOlderThan = 14d
[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d
내가 사용한 첫 번째 완전한 명령은 다음과 같습니다.
find -name inputs.conf -exec sed -ie 's/\(\[monitor:.*\]\)/\1\nignoreOlderThan = 14d/g' {} +
이것은 작동합니다. ignoreOlderThan = 14d
바로 뒤에 추가 되었습니다 [monitor://...]
.
두 번째는 더 복잡하고 작동하지 않습니다.
find -name inputs.conf -exec sed -ie 's/\(\[monitor[^\]]+\][^\[]?\)\(ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+?ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+\)?/\1\3\4/g' {} +
regex101을 사용하여 몇 가지 가능한 시나리오를 테스트했습니다.
https://regex101.com/r/okCSfl/6
https://regex101.com/r/okCSfl/7
https://regex101.com/r/okCSfl/8
https://regex101.com/r/okCSfl/9
정규식은 작동하므로 문제는 sed 명령 어딘가에 있고 능력이 훨씬 떨어지는 것 같습니다. 캡처 그룹에 필요에 따라 대괄호를 이스케이프 처리했으며 명령이 실행되지만 아무 작업도 수행되지 않습니다. 가끔 네 번째 캡처 그룹이 없기 때문일 수도 있다고 생각했지만 각 그룹에 4개의 캡처 그룹이 모두 포함된 파일도 테스트했습니다.
나는 또한 일부 sed가 모든 것을 한 줄로 해석한다는 것을 읽었습니다. 이것이 바로 내 테스트 케이스 중 일부가 개행 사이에 공백이 전혀 없는 이유입니다.
편집: @choroba는 sed가 한 번에 한 줄씩 실행된다는 점을 지적하고 perl을 제안하고 예제를 제공했습니다. 나는 그것을 가지고 놀았고 다음과 같이 작동하게 만들었습니다.
find -name inputs.conf -exec perl -0777 -pi -e 's/(\[monitor:[^[]+?)^(ignoreOlderThan\s?=\s?[0-9]+\w)([^[]+?^ignoreOlderThan\s?=\s?[0-9]+\w[^[]+)/$1$3/gms' {} +
여기 데모:
답변1
sed는 입력을 한 줄씩 처리합니다. 정규식은 여러 줄을 쉽게 일치시킬 수 없습니다.
반면 Perl은 -0777
옵션이 지정되면 전체 파일을 읽을 수 있습니다.
perl -0777 -pe 's/^(\[monitor:[^[]+^ignoreOlderThan .*)^ignoreOlderThan = \w+/$1/gms' input > output
-0777
전체 파일을 먹어라-p
처리 후 인쇄 입력/g
교체를 반복/s
개행 문자 일치.
(보통 그렇지 않음)/m
^
전체 문자열뿐만 아니라 각 개행의 시작 부분에서 일치합니다(비슷$
하지만 여기서는 필요하지 않음).