sed는 태그를 변경하고 콘텐츠의 일부를 유지합니다.

sed는 태그를 변경하고 콘텐츠의 일부를 유지합니다.

URL이 포함된 태그가 여러 번 나타나는 큰 텍스트 파일이 있습니다.

[tag]https://example.com/222389/link/11835457224168404[/tag]

다음과 같이 레이블 형식을 다시 지정해야 합니다.

[new-tag]11835457224168404[/new-tag]

("link"("id") 뒤의 URL 부분만 캡처하고 태그를 "new-tag"로 수정합니다.

  • 각 줄에는 여러 개의 레이블이 있을 수 있습니다.
  • 태그 위치는 일정하지 않습니다. 파일 전체에서 무작위로 나타납니다.
  • 태그 내용 시작 부분에 공백('http')이 있을 수 있습니다. 'http://' 또는 'https://'를 사용하고, 때로는 'www'도 사용합니다.
  • 태그의 끝 부분("id" 뒤)에 다음과 같이 내용이나 공백이 있는 경우가 있습니다.

    [tag]https://example.com/222389/link/11835457224168404/qwertyiop[/tag]
    

    또는

    [tag]https://example.com/222389/link/11835457224168404?link=11835457224168401    [/tag]
    
  • 때로는 ([/tag] 또는 "http"를 닫지 않고) 단독으로 나타나는 "[tag]"를 무시해야 하는 경우도 있습니다.

sed나 대안을 사용하여 이 작업을 어떻게 수행할 수 있나요?

답변1

전략

정규식을 작성하는 것이 가능하지만아니요다중 문자 문자열을 일치시키면 복잡해질 수 있습니다. [tag]합계를 [/tag]단일 문자로 변환 하는 트릭을 사용한 다음 부정 문자 클래스를 사용하겠습니다. 이 스크립트에서는 컨트롤-a와 컨트롤-b를 사용하겠습니다. 이것은비판적인이러한 문자는 파일에 나타나지 않습니다. 이것들은 입력하기 어렵기 때문에 몇 가지 변수를 여는 태그와 닫는 태그로 s사용 하겠습니다 . 닫는 태그가 아닌 일련의 문자를 나타내는 e데 사용합니다 .notend

#!/bin/bash
s=$'\001' # control-a, for the start tag 
e=$'\002' # control-b, for the end tag
notend="[^$e]*" # expression for not the end tag.
# Program, Change the tags into single characters
# change matched pairs of tags into new form
# convert any unmatched tags back to original form
prog='
s:\[tag]:'"$s"':g
s:\[/tag]:'"$e"':g
s:'"$s$notend"'/link/\([0-9]*\)'"$notend$e"':[new-tag]\1[/newtag]:g
s:'"$s"':[tag]:g
s:'"$e"':[/tag]:g'

# run sed, passing any parameters  
sed -e "$prog" "$@"

용법

이 스크립트를 저장하고 실행 가능하게 만든 후 실행하여 데이터 파일을 인수로 전달하고 출력을 임시 파일로 리디렉션합니다. 임시 파일을 확인하세요.

관련 정보