다음은 "\t"로 구분된 두 개의 열을 포함하는 내 파일입니다.
a HK97 family prohead protease [Lomovskayavirus C31]
b major capsid protein [Lomovskayavirus C31]
c gp12 [Lomovskayavirus C31]
d gp19 [Lomovskayavirus C31]
sed가 이와 같은 파일을 얻을 수 있기를 바랍니다.
a Lomovskayavirus C31
b Lomovskayavirus C31
c Lomovskayavirus C31
d Lomovskayavirus C31
명령을 시도했지만 sed 's/.*[\(.*\)].*/\1/'
작동하지 않는 것 같습니다. 그러면 무엇을 바꿔야 할까요? 감사해요.
답변1
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ awk -F '[][\t]' -v OFS='\t' '{print $1, $3}' file
a Lomovskayavirus C31
b Lomovskayavirus C31
c Lomovskayavirus C31
d Lomovskayavirus C31
답변2
[
and ]
는 특별한 의미(나중에 필요하게 될 일치할 문자 집합)를 갖기 때문에 이스케이프해야 하며 다음과 같은 결과를 얻습니다.
sed 's/.*\[\(.*\)\].*/\1/'
하지만 이렇게 하면 첫 번째 열도 삭제되므로 시도해 보세요.
sed 's/[ [:alnum:]]*\[\(.*\)\].*/\1/'
따라서 첫 번째 부분은 모든 영숫자 문자와 공백을 캡처하지만 탭 문자는 캡처하지 않으므로 탭 문자 뒤의 모든 내용이 제거됩니다.
답변3
사용행복하다(이전 Perl_6)
perl6 -ne 'given .split(/\s+/, 2) { put (.[0], .[1].match: / <?after "[" > .+ <?before "]" > /).join("\t") };'
또는
raku -ne 'given .split(/\s+/, 2) { put (.[0], .[1].comb: / "[" <(.+)> "]" /.[0]).join("\t") };'
Perl 언어 계열은 까다로운 정규식 문제를 해결하는 좋은 방법입니다. 위의 두 가지 전략은 혼합 및 일치될 수 있습니다. 즉, 캡처 태그 comb
뿐만 아니라 미리보기/뒤돌아보기 어설션을 사용할 수 있습니다 match
.
위의 첫 번째 예에서는 각 줄에 공백이 split
있지만 두 조각 \s+
으로만 나누어집니다 . 그런 다음 첫 번째 요소를 배치하고 2
두 번째 요소에서 match
패턴을 검색합니다 <?after "[" > .+ <?before "]" >
. 정규식 원자는 <?after … >
Raku의 긍정적 예측 어설션입니다. <?before … >
정규식 원자는 Raku의 긍정적 예측 어설션입니다. 이러한 어설션은 너비가 0이므로 캡처 마커가 필요하지 않으며 일치 변수( $/
or )를 직접 출력할 수 있습니다.$<>
두 번째 예에서는 split
각 줄을 \s+
여백에 배치하고 다시 2
두 개의 조각으로만 분할합니다. 첫 번째 요소를 다시 배치하고 두 번째 요소를 반복하여 및로 둘러싸인 하나 이상의 문자를 comb
찾습니다 . .+
Raku의 ...capture 플래그는 출력에서 괄호를 제외하는 데 사용됩니다(두 번째 열에서 첫 번째 ed 발생을 반환하기 위해 끝에 인덱스를 추가).[
]
<(
)>
.[0]
comb
입력 예:
a HK97 family prohead protease [Lomovskayavirus C31]
b major capsid protein [Lomovskayavirus C31]
c gp12 [Lomovskayavirus C31]
d gp19 [Lomovskayavirus C31]
출력 예(위의 두 예):
a Lomovskayavirus C31
b Lomovskayavirus C31
c Lomovskayavirus C31
d Lomovskayavirus C31
어쨌든 첫 번째 열을 삭제하려면 위 코드를 다음과 같이 단순화할 수 있습니다.
raku -ne 'put m/ <?after \[> .+ <?before \]> /;'
또는
raku -ne 'put .comb(/ \[ <(.+)> \] /).[0];'
답변4
사용sed
$ sed -E 's/( +)[^[]*\[([^]]*).*/\1\2/' input_file
a Lomovskayavirus C31
b Lomovskayavirus C31
c Lomovskayavirus C31
d Lomovskayavirus C31