문자열에서 일치하지 않는 부분만 인쇄하고 싶습니다. 반대 옵션이 있습니까 grep -o
? grep -v
패턴이 포함된 문자열을 완전히 무시하기 때문이 아닙니다 .
내가 가지고 있다고 가정 해 봅시다 :
setenv var "/home/user/dir/subdir/case"
setenv path "/home/user/dir"
그냥 돌아가야 하는데 subdir/case
쉽게 할 수 있는 방법을 찾을 수 없습니다 grep
.
grep -o
일치하는 문자열 부분만 반환되는 경우 일치하지 않는 문자열 부분만 반환하는 네거티브 옵션이 있나요?
답변1
Perl 또는 Perl을 사용하면 sed
패턴과 일치하는 줄의 일부를 삭제하고 나머지 줄을 인쇄할 수 있습니다. 샘플 데이터가 다음 위치에 있다고 가정합니다 file.txt
.
$ sed -ne 's/^setenv var *//p' < file.txt
"/home/user/dir/subdir/case"
당신이 얻는 것에 대해 요구하는 것은 실제로 subdir/case
끝 인용문도 있기 때문에 두 부분을 제거해야 합니다. 캡처 그룹을 사용하면 중간에서 부분을 가져오는 것이 더 쉽습니다. 여기서 섹션 에서는 문자열 중 이때 맞는 부분을 저장하라고 (.*)
하고 , 바꾸기 섹션에서는 일치하는 것을 모두 바꾸라고 합니다. print( ) 명령은 여기서 replacement()가 일치하는 조건에 따라 실행됩니다 . 패턴 자체에 나타나기 때문에 구분 기호로 사용하고 있지만 어떤 문자든 사용할 수 있습니다.sed
\1
p
s///
,
/
$ sed -nEe 's,^setenv var *"/home/user/dir/(.*)".*,\1,p' < file.txt
subdir/case
또는 Perl에서는 아무것도 바꾸지 않고 일치 항목에서 캡처된 부분만 인쇄합니다.
$ perl -lne 'print $1 if m,^setenv var *"/home/user/dir/(.*)",' < file.txt
subdir/case
위의 두 가지 모두 패턴과 일치하지 않는 줄에 대해서는 아무것도 인쇄하지 않습니다.
전체 내용을 인쇄하려면 무조건 인쇄하세요(앞의 세미콜론 참고 p
).
$ sed -nEe 's,^setenv var *"/home/user/dir/(.*)",\1,; p' < file.txt
subdir/case
setenv path "/home/user/dir"
또는
$ perl -lne 's,^setenv var *"/home/user/dir/(.*)",$1,; print' < file.txt
subdir/case
setenv path "/home/user/dir"
답변2
내가 올바르게 이해했다면 사용할 수 있습니다GNU grep그리고lookbehind assertion
그리고lookahead assertion
:
# return what doesn't match 'dir/' at the end of the line
# and doesn't match the final double quote '"'
$ grep -Po '(?<=dir/).*(?="$)' file
subdir/case
dir/
이는 이전의 "부정적" 모드를 가정합니다 subdir/case
. 모드가 전체 디렉터리인 경우:
grep -Po '(?<="/home/user/dir/).*(?="$)' file