다음 내용이 포함된 파일이 있습니다.
..\..\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를 사용하여 어떻게 이를 달성할 수 있나요?
두 그룹을 모두 캡처하는 정규식을 작성할 수 없습니다.
- 초기 그룹(....\src) - 모든 줄에서 동일합니다.
- 변수 그룹 (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 grep
와paste
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 }'