몇 시간 동안 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'