OS X의 sed - 대괄호 사이의 모든 텍스트를 추출합니다.

OS X의 sed - 대괄호 사이의 모든 텍스트를 추출합니다.

주어진 흐름은 다음과 같습니다.

[foo] 123 [bar]
[gar] dsa [har] 345
[uf] 88 [gc] 43 [br]

이를 처리하기 위해 sed(또는 다른 것)를 사용하고 싶으므로 출력은 다음과 같습니다.

foo bar
gar har
uf gc br

나는 노력했다cat myfile | sed -e 's/^.*\[//;s/\].*$//'

하지만 그것은 나에게 마지막 인스턴스만을 제공합니다.

내 실제 입력은 다음과 같습니다.

53f42d4 [the contacts are duplicated] Adding support in picking email verified users [https://trello.com/c/663]
3c454b0 [the contacts are duplicated] splitting contact by phone numbers and emails and changing contact model to contain only 1 email [https://trello.com/c/663]
0e63e5b [we should not let a user confirm his email if we have a user with this confirmed email already] better doc [https://trello.com/c/643]
02671b7 [we should not let a user confirm his email if we have a user with this confirmed email already] preventing updating email if already in used by other user [https://trello.com/c/643]

그래서 나는 첫 번째 줄을 얻고 싶습니다 :

the contacts are duplicated https://trello.com/c/663

답변1

awk도 이에 적합합니다.[ 또는 ]필드 구분 기호로 각각 인쇄우수대지:

awk -F '[][]' '{for (i=2; i<=NF; i+=2) {printf "%s ", $i}; print ""}' file

sed를 사용하여 다음과 같이 작성합니다.

sed -E 's/(^|\])[^[]*($|\[)/ /g' file

답변2

이는 첫 번째(왼쪽) 대괄호 안의 모든 항목을 여러 번 뒤에 오는 첫 번째(오른쪽) 대괄호와 일치시킵니다.

$ sed 's/[^[]*\[\([^]]*\)\][^[]*/\1 /g' file
foo bar
gar har
uf gc br

설명하다:

sed '                      # start a sed script
        s/                 # start a substitute command
        [^[]*              # match all leading characters (except [)
        \[                 # match an explicit [
        \([^]]*\)          # capture text inside brackets.
        \]                 # match the closing ]
        [^[]*              # match trailing text (if any).
        /\1 /              # replace everything matched by the captured text.
        g                  # repeat for all the line.
       ' file              # close script. Apply to file.

이렇게 하면 각 일치 항목에 후행 공백이 추가됩니다. 삭제해야 하는 경우 끝에 delete를 추가하세요.

sed -e 's/[^[]*\[\([^]]*\)\][^[]*/\1 /g' -e 's/ $//' file

GNU grep이 있으면 도움이 될 수 있습니다(한 번에 한 줄씩 캡처).

grep -Po '\[\K[^]]*(?=])'

그리고 위의 방법이 작동하지 않으면 awk도 작동할 수 있습니다.

awk '{print gensub(/\[([^]]*)\][^[]*/,"\\1 ","g")}' file

답변3

관용적인 접근 방식은 Lookaround 어설션을 사용하는 것입니다.https://www.regular-expressions.info/lookaround.html, 그러나 sed는 이를 지원하지 않으며 PCRE 호환 정규식 프로세서에서만 지원합니다.

Perl은 기본적으로 macOS에서 사용할 수 있어야 하므로 이것이 실행 가능한 대안일 수 있습니다.

Perl을 사용하면 다음과 같이 말할 수 있습니다.

perl -pe 's/.+?(?<=\[)(.+?)(?=\]).+?/$1 /g'

(줄 끝에 공백이 추가됩니다.)

이 패턴에 대한 설명은 다음을 참조하세요.https://regexr.com/41gi5.

답변4

사용:

sed -n '/\[/ { s-[^[]*--; s-\[\([^]]*\)\][^[]*- \1-g; s- --p }'

알고리즘은 다음과 같습니다.

  • 괄호가 포함되지 않은 줄은 무시하세요.
  • 첫 번째 대괄호 앞의 텍스트를 제거합니다.
  • 대괄호 쌍과 선택적 후행 텍스트를 공백으로 바꾸고 대괄호 안의 텍스트는 그대로 둡니다.
  • 초기 공백을 제거하고 중간 공백만 유지합니다.

관련 정보