두 정규식 패턴 사이의 문자열 제거

두 정규식 패턴 사이의 문자열 제거

다음 내용이 포함된 파일이 있습니다.

..\..\src\modules\core\abc\abc.cpp
..\..\src\modules\core\something\xyz\xyz.cpp
..\..\src\other_modules\new_core\something\pqr\pqr.cpp
..\..\src\other_modules\new_core\something\pqr\abc.cpp

내가 기대하는 결과는

..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

sed를 사용하여 어떻게 이를 달성할 수 있나요?

두 그룹을 모두 캡처하는 정규식을 작성할 수 없습니다.

  1. 초기 그룹(....\src) - 모든 줄에서 동일합니다.
  2. 변수 그룹 (abc\abc.cpp) 또는 (xyz\xyz.cpp) 또는 (pqr\pqr.cpp) 또는 (pqr\abc.cpp)

답변1

BSD sed또는 최신 버전의 GNU 사용 sed(이전 버전의 경우 -E로 대체 -r):

sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
  • #입력에 s가 포함된 모호성을 피하기 위해 s대체() 명령에 대한 구분 기호로 사용됩니다 .sed\

  • (.*\\src)처음부터 일치를 시작 src하고 일치 항목을 캡처 그룹 1에 넣습니다.

  • (\\[^\]+\\[^\]+$)두 개의 가 있는 부분을 끝까지 일치 \시켜 캡처 그룹 2에 넣습니다. .*앞선 것은 첫 번째 캡처 그룹과 두 번째 캡처 그룹 사이의 모든 항목과 일치합니다.

  • 교체에서는 두 개의 캡처된 그룹을 사용했습니다.

POSIX 스타일:

sed 's#\(.*\\src\).*\(\\[^\]\+\\[^\]\+$\)#\1\2#' file.txt

예:

% cat file.txt
..\..\src\modules\core\abc\abc.cpp
..\..\src\modules\core\something\xyz\xyz.cpp
..\..\src\other_modules\new_core\something\pqr\pqr.cpp
..\..\src\other_modules\new_core\something\pqr\abc.cpp

% sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

답변2

대체 솔루션:

GNU greppaste

grep두 개의 패턴을 추출 .*\\src하거나 (\\[^\]+){2}$별도의 라인에 인쇄합니다. 그런 다음 결합된 출력을 사용합니다.paste

$ grep -oE '.*\\src|(\\[^\]+){2}$' ip.txt | paste -d '' - -
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

그리고perl

$ perl -pe 's/.*\\src\K.*(?=(\\[^\\]+){2}$)//' ip.txt 
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp

여기서는 활성 탐색을 사용하여 모드 간 텍스트를 .*\\src제거 합니다.(\\[^\\]+){2}$

답변3

데이터가 포함된 파일 만들기

-rwxr-xr-x. 1 sasi   webApp  190 Oct  4 13:42 file.txt

다음 명령을 실행하십시오.

[sasi@localhost temp]$ sed -E 's#(.*\\src).*(\\[^\]+\\[^\]+$)#\1\2#' file.txt
..\..\src\abc\abc.cpp
..\..\src\xyz\xyz.cpp
..\..\src\pqr\pqr.cpp
..\..\src\pqr\abc.cpp
[sasi@localhost temp]$
[sasi@localhost temp]$
[sasi@localhost temp]$

답변4

정규식으로 공격하는 이유는 무엇입니까? 경로 수정에는 정규식이 필요하지 않습니다. 운영 체제 커널은 경로를 추적하기 위해 정규식을 사용하지 않습니다.

Awk를 사용하면 백슬래시를 구분 기호로 사용하고 구성 요소는 필드가 됩니다.

awk 'BEGIN { FS = OFS = "\\" } { print $1, $2, $3, $(NF-1), $NF }'

관련 정보