마크다운 파일을 수정하려고 합니다. 파일에는 이와 같은 링크가 많이 있습니다.
[string one](/stringtwo/#stringthree)
나는 그것들을 다음과 같이 바꾸고 싶습니다 :
[string one](stringtwo.html#stringthree)
슬래시를 제거하고 .html
.
나는 다음을 시도했다:
sed -i 's/](\(\/.*\)#/](\1.html#/g' file
하지만 돌아왔다 [global configuration](/config/.html#globals)
. 슬래시는 제거되지 않습니다.
bash
또는를 사용하여 어떻게 이를 달성할 수 있습니까 sed
?
답변1
이것은 트릭을 수행하는 것 같습니다
$ cat 725364.in
[string one](/stringtwo/#stringthree)
[example label](/path/to/doc/#anchor)
$ sed 's_\(\[[^]]*]\)(/\([^#]*\)/\(#[^)]*\))_\1(\2.html\3)_g' 725364.in
[string one](stringtwo.html#stringthree)
[example label](path/to/doc.html#anchor)
그것을 파괴:
첫째, 리터럴 s의 탈출을 피하기 위해 so 대신 s_needle_pin_flags
for를 사용합니다 .sed
s/needle/pin/flags
/
sed
검색은 이 표현식을 사용하여 수행되며 \(\[[^]]*]\)(/\([^#]*\)/\(#[^)]*\))
다음과 같이 분류됩니다.
\(\[[^]]*]\)
- 그룹 1의 정의(링크 태그):- 문자 그대로의 의미
[
- 그 뒤에는 0개 이상 또는
]
- 문자 그대로의 의미가 뒤따른다.
]
- 문자 그대로의 의미
(/
- 문자 그대로의 의미(/
\([^#]*\)
- 그룹 2의 정의(URL):- 0개 이상의 비리터럴 콘텐츠
#
- 0개 이상의 비리터럴 콘텐츠
/
- 문자 그대로의 의미/
\(#[^)]*\)
- 그룹 3(앵커)의 정의:- 문자 그대로의 의미
#
- 그 뒤에 0개 이상의 텍스트가 아닌 콘텐츠가 옵니다.
)
- 문자 그대로의 의미
)
- 문자 그대로의 의미)
다음을 사용하여 변환합니다 \1(\2.html\3)
.
- 그룹 1 경기에 이어
(
, 이어서- 그룹 2 경기에 이어
.html
, 이어서- 그룹 3 경기 이후
)
답변2
\1
일치하는 그룹에는 's/](\(\/.*\)#/](\1.html#/g'
슬래시가 포함되어 있습니다. \/
그룹 외부에 지정해야 합니다 \(\/.*\)
. 이 시도:
sed -i 's/](\/\(.*\)\/#/](\1.html#/g' file
답변3
사용행복하다(이전 Perl_6)
~$ raku -pe 's{ \( ~ \) [(\/) ( .+? ) (\/) (\# .+ )] $ } = "($1.html$3)";' 725364.in
#OR(더 격식을 차림)
~$ raku -pe 's{ \( ~ \) [(\/) ( <-[#]>+? ) (\/) (\# <-[#]>+ )] $ } = "($1.html$3)";' 725364.in
입력 예(@DopeGhoti 덕분에):
[string one](/stringtwo/#stringthree)
[example label](/path/to/doc/#anchor)
예제 출력:
[string one](stringtwo.html#stringthree)
[example label](path/to/doc.html#anchor)
OP는 /
슬래시를 변경하기를 원했기 때문에 s///
일반 Raku 대체 구문과 다른 구문이 사용되었습니다. Raku는 s{ … } = " … "
위에서 사용된 대체 구문(또는 등) 도 제공합니다 s[ … ] = " … "
.
첫 번째 원자에서는 ~
Raku의 중첩된 데이터 구조 물결표 구문이 사용됩니다. 기본적으로 정규식은 다음과 같이 \( ~ \) [ … ]
말합니다."대괄호 안의 그룹은 대괄호로 둘러싸여 있습니다.". 그런 다음 정규식은 /
슬래시를 로 $0
, 탐욕스럽지 않은 문자 시퀀스를 로 $1
, 두 번째 /
슬래시를, $2
octothorpe into로 시작된 터미널 탐욕스러운 문자 시퀀스를 캡처합니다.#
$3
캡처 표시( -pe
플래그를 다음으로 변경 -ne
하고 추가 say
):
~$ perl6 -ne 'say s{ \( ~ \) [(\/) ( .+? ) (\/) (\# .+ )] $ } = "($1.html$3)";' 725364.in
「(/stringtwo/#stringthree)」
0 => 「/」
1 => 「stringtwo」
2 => 「/」
3 => 「#stringthree」
「(/path/to/doc/#anchor)」
0 => 「/」
1 => 「path/to/doc」
2 => 「/」
3 => 「#anchor」
대신에 잡히지 않은 괄호가 복원됩니다. 캡처된 /
슬래시는 삭제됩니다. 캡처된 경로 $1
와 캡처된 옥토소프가 실행된 터미널 문자열을 출력 .html
합니다 .$3
#