SED 챌린지, 중괄호가 포함된 문자열 집계

SED 챌린지, 중괄호가 포함된 문자열 집계

몇 시간 동안 sed를 사용하여 텍스트의 특정 문자열 패턴을 집계하려고 시도했지만 해결책을 찾을 수 없습니다. 나는 너희들이 무엇을 해야할지 알고 있기를 바랍니다! ?

  • 내 대상의 텍스트는 문자열 문자로만 구성됩니다(보이지 않는 \t가 존재하지 않음).
  • (TAB)을 포함하지만 적어도 두 개는 서로 인접하고 최대 8개는 서로 인접해 있는 문자열 부분을 찾아 단일(TAB) 항목으로 바꾸고 싶습니다.

  • 검색은 bash 스크립트가 포함된 셸 파일에서 수행되어야 합니다.

예:

#!/bin/bash

text="Column One(TAB)(TAB)(TAB)Column Two(TAB)(TAB)Column three(TAB)Column4"

modText=`echo $text | sed 's/([(]\{1\}TAB[)]\{1\})\{2,8\}/(TAB)/g'`
  • 나는 여러 버전의 sed-command를 시도했는데 위의 내용은 그 중 하나일 뿐입니다. 내 초기 생각은 modText=`echo $text | sed 's/\(TAB\)\{1\})\{2,8\}/(TAB)/g'`였습니다.

당신이 나를 도울 수 있다면 좋을 것입니다. 해결책이 그다지 멀지 않은 것처럼 느껴지지만 더 이상 아이디어가 없으며 내 연구에서도 제대로 이루어지지 않았습니다. :-S


텍스트 예시

"첫 번째 열(TAB)(TAB)(TAB) 두 번째 열(TAB)(TAB) 세 번째 열(TAB) 네 번째 열"

내 검색 기준은 "첫 번째 열"과 "세 번째 열" 사이에 나타나는 처음 두 개(TAB) 그룹과 일치합니다.

결과다음과 같아야 합니다.

"첫 번째 열(TAB) 두 번째 열(TAB) 세 번째 열(TAB) 네 번째 열"

답변1

"최대 8" 조항이 어떻게 적용되는지 잘 모르겠지만 순진한 접근 방식은 다음과 같습니다.

sed 's/\((TAB)\)\{2,8\}/(TAB)/g'

답변2

인접한 s가 8개보다 많으면 교체가 발생하지 않아야 한다는 뜻이라면 (TAB)다음과 같이 할 수 있습니다.

sed '
   s/_/_u/g; # escape _
   s/|/_p/g; # escape |
   s/(TAB)/|/g; # use a single character in place of (TAB)
   s/.*/<&>/; # add leading and trailing non-| character
   s/\([^|]\)|\{2,8\}\([^|]\)/\1|\2/; # replace up to 8 | provided
                                      # they are not preceded nor followed
                                      # by |
   s/.\(.*\)./\1/; # undo wrapping
   s/|/(TAB)/g;    # undo replacement
   s/_p/|/g;s/_u/_/g; # undo escaping'

Perl과 같은 정규 표현식을 지원하는 경우 sed(예 ssed:) 둘러보기 연산자를 사용할 수 있습니다.

ssed -R 's/(?<!\(TAB\))(\(TAB\)){2,8}(?!\(TAB\))/(TAB)/g'

또는 perl직접 사용하십시오.

perl -lpe 's/(?<!\(TAB\))(\(TAB\)){2,8}(?!\(TAB\))/(TAB)/g'

AT&T(ast-open)는 / 옵션을 sed사용하여 확장 정규식을 지원합니다.-A-X향상된하나 있다부정적인연산자( x!) 및접속사운영자( x&y). 거기에서 (.{5}&(\(TAB\))!)5개의 문자 시퀀스를 일치시킵니다.아니요 (TAB). 따라서 sed다음을 수행할 수 있습니다.

sed -A '
  :1
    s/(^.{0,4}|.{5}&(\(TAB\))!)(\(TAB\)){2,8}(.{0,4}$|.{5}&(\(TAB\))!)/\1(TAB)\4/
  t1'

관련 정보