다음과 같은 파일이 있습니다.
1 foo
1 bar
1 someOtherString
2 contains bar and more
2 test
3 contains a random string
4 some other string
2 don't remove this line bar
2 but remove this line
14 keep this line
21 and also this line
7 bar
이 파일에서 다음 파일을 가져오고 싶습니다.
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
원래:
- "1" 또는 "2"로 시작하지 않는 모든 줄을 유지합니다.
- "foo" 또는 "bar"를 포함하는 모든 줄을 유지합니다.
- 다른 모든 줄 삭제
- 주문을 그대로 유지하세요
답변1
라는 파일의 데이터를 고려하십시오 file
. 예제 결과를 얻기 위한 요구 사항은 게시한 설명과 약간 다릅니다.
file
다음 조건 중 하나와 일치하는 모든 행을 유지합니다.- nor (숫자 뒤에 공백이 있음) 로
1
시작 하지 마세요.2
- 포함
foo
하거나bar
- nor (숫자 뒤에 공백이 있음) 로
- 다른 모든 줄 삭제
- 주문을 그대로 유지하세요
perl
이는 두 표현식을 일치시키고 일치할 때 해당 줄을 (순서대로) 인쇄하여 표현할 수 있습니다.
perl -ne '( !/^(1 |2 )/ or /foo|bar/ ) and print' file
돌이켜 보면 전체 요구 사항이 약간 다르게 표현되었을 수 있습니다.
- 각 행마다 차례로
1
행이 또는로 시작 하지 않으면 해당 행을 인쇄하십시오.2
foo
또는bar
이는 awk
매우 편리하게 매핑됩니다.
awk '!/^(1 |2 )/ || /foo/ || /bar/' file
두 경우( perl
및 awk
) 모두에서 RE는 ^(1 |2 )
공통 인자를 도출하고 이를 다음과 같이 다시 작성하여 단순화할 수 있습니다 ^[12]
.
perl -ne '( !/^[12] / or /foo|bar/ ) and print' file
awk '!/^[12] / || /foo/ || /bar/' file
답변2
사용 sed
:
$ sed '/^[12]\>/ { /foo/ !{ /bar/ !d; }; }' file
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
위의 코드는 sed
각 줄이 단어가 아닌 문자( 원하는 경우 단일 공백으로 대체할 수 있음) 로 시작하는지 1
또는 뒤에 오는지 테스트합니다. 그렇지 않은 경우 행을 인쇄하십시오. 그렇다면 해당 줄의 하위 문자열을 테스트하세요 . 하위 문자열이 존재하면 해당 줄을 인쇄합니다. 존재하지 않는 경우 pair 에 대해 유사한 테스트를 수행하고 , 일치하는 경우 행을 인쇄하고, 일치하지 않는 경우 행을 삭제합니다.2
\>
foo
bar
논리를 거꾸로 읽으십시오 d
. 일치하지 bar
않고 일치하지 않지만 foo
또는 1
으로 시작하는 줄은 삭제됩니다 2
.
답변3
Raku(이전 Perl_6) 사용
raku -ne '.put if .grep( !/^ [ 1 | 2 ] \s / | / foo | bar / );'
또는
raku -ne '.put if .grep( { !/^ [ 1 | 2 ] \s /} | / foo | bar / );'
또는
raku -ne '.put if .grep( (none /^ [ 1 | 2 ] \s /) | / foo | bar / );'
입력 예:
1 foo
1 bar
1 someOtherString
2 contains bar and more
2 test
3 contains a random string
4 some other string
2 don't remove this line bar
2 but remove this line
14 keep this line
21 and also this line
7 bar
예제 출력:
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
위의 내용은 @roaima의 Perl5 코드를 대략적으로 번역한 것입니다. 하지만 이는 실제로 Raku에서의 작업입니다 grep
. Raku에서는 !
부정 연산자(주변 코드 블록 유무에 관계없이 위에 표시됨 {...}
)를 사용하거나 연결(Raku와 관련됨 none
)을 사용하여 패턴이 있는지 테스트할 수 있습니다.Sets
\s
정규식에 문자가 포함되어 있음을 알 수 있습니다. 이는 선언되지 않은 ( \s
) 공백 및/또는"...정규식에서 인용되지 않은 공백은 일반적으로 무시됩니다..."Raku에서는 기본적으로 코드를 더 읽기 쉽게 만듭니다. 아래 링크를 참조하세요.
답변4
우리는 다음과 같은 다중 기준 검색을 수행하기 위해 둘러보기를 유익하게 사용할 수 있습니다.
$ grep -vP '^(?=[12]\h)(?!.*(?:foo|bar))' file
Python은 re 모듈과 협력하여 검색 결과 상태에 따라 일치하고 필터링할 수 있습니다.
python3 -c 'import re, sys
with open(sys.argv[1]) as f:
print(*filter(lambda x: re.match(r"(?![12]\s)",x) or re.search(r"foo|bar",x),f),sep="",end="")
' file