여러 줄의 정규 표현식을 쉽게 검색하고 교체할 수 있는 명령줄 도구

여러 줄의 정규 표현식을 쉽게 검색하고 교체할 수 있는 명령줄 도구

나는 텍스트 편집기를 사용할 때 검색 및 바꾸기에 PCRE 정규식을 자주 사용하는데, 다음 과 같은 강력한 Unix 명령 줄 도구에서 검색 및 바꾸기 perl에 PCRE 정규식이 사용된다는 사실을 알고 매우 속상합니다. 정규식은 매우 복잡하며 모든 상황에서 기억하기 어려운 모든 종류의 구문이 필요합니다.awksed

더 복잡한 여러 줄 정규식을 사용하여 검색하고 바꾸는 작업(전체 파일의 모든 항목에 대해)을 다음과 같이 간단하게 수행할 수 있는 Linux용 명령줄 도구가 있습니까?

magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/' file.txt

즉, 일치시킬 정규식은 텍스트 편집기의 필드에 입력한 것과 동일합니다 search for. 대체 문자열은 여러 줄의 정규식도 처리할 수 있으며 복잡한 구문이 필요하지 않습니다.

편집하다:

요청에 따라 입력을 첨부했으며 위 정규식 예제를 사용하여 실제로 수행하려는 작업을 설명하겠습니다.

다음과 같이 입력하세요.

2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:13 > user joined the channel.
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected

다음과 같은 출력이 생성되어야 합니다.

2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected

정규식은 포함된 줄과 일치 [username] joined the channel하고 그 아래에 포함된 줄을 찾습니다.[username] disconnected ~하지 않는 한이 두 줄 사이에는 or 가 있습니다 [username] was kicked from channel..[username] was banned from channel.

그런 다음 대체 문자열은 해당 행 뒤의 모든 행을 일치하는 패턴으로 대체하여 [username] joined the channel위의 입력에서 해당 행을 효과적으로 제거합니다.2016-05-16 06:20:13 > user joined the channel.

아마도 당신에게는 별 의미가 없을 것입니다만,이것은 제가 최근에 작업했던 것과 비슷한 정규식 샘플입니다. 나는 이 특정한 문제나 위에 나열된 Unix 도구와 관련된 유사한 문제에 대한 해결책을 찾고 있는 것이 아니라는 점을 명심하십시오. 수정되지 않은 "검색"을 사용하고 텍스트 편집기(특히 Geany, 그러나 중요하지 않음)에서 사용하는 문자열을 복잡한 구문이나 추가 사항 없이 사용할 수 있는 명령줄 도구를 찾고 있습니다. 처리할 프로그래밍 논리 여러 줄의 "검색" 및 문자열 교체.

답변1

여기서 Perl이 왜 허용되지 않는지 모르겠습니다. 제공한 입력을 기반으로 이 줄은 요청한 출력을 제공합니다.

perl -0777p -e 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt

이 매개변수는 정규 표현식 수정자를 추가한 것을 제외하고는 -e정확히 첫 번째 매개변수입니다 . 이것은 "수정되지 않은" 것은 아닐 수도 있지만, 불합리해 보이지도 않습니다. 전체 줄을 입력하지 않으려면 이 스크립트를 다음과 같이 작성할 수 있습니다.magicregextool/mgmagicregextool

#!/usr/bin/perl -0777p
BEGIN { $::arg = shift @ARGV; }
eval $arg;

심지어:

#!/bin/sh
perl -0777pe $*

그런 다음 다음을 입력하면 됩니다.

magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt

이는 예시와 동일합니다(수정자 추가 제외 /mg).

또 다른 이점은 각 파일에 대해 여러 관련 검색/바꾸기 작업을 실행하는 경우 해당 작업을 동일한 스크립트에 넣을 수 있다는 것입니다.

#!/usr/bin/perl -0777p
s/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg;
s/(some other\n)matched text/\1/mg;

관련 정보