
다음 내용이 포함된 파일이 있습니다.
..\..\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에 넣습니다.(\\[^\]+\\[^\]+$)
\
끝까지 두 개의 s가 있는 부분과 일치 하고 캡처된 그룹 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
왜 이것을 정규식으로 강타합니까? 경로 병합에는 정규 표현식이 필요하지 않습니다. OS 커널은 경로를 따르기 위해 정규식을 사용하지 않습니다.
Awk에서는 백슬래시를 구분 기호로 사용하고 구성 요소는 필드가 됩니다.
awk 'BEGIN { FS = OFS = "\\" } { print $1, $2, $3, $(NF-1), $NF }'