일치하는 패턴을 편집한 다음 바꾸는 더 강력한 방법이 있습니까?

일치하는 패턴을 편집한 다음 바꾸는 더 강력한 방법이 있습니까?

일치하는 패턴을 편집한 다음 다른 패턴을 편집된 패턴으로 바꾸는 방법이 있습니까?

입력하다:

a11.t
some text here
a06.t
some text here

산출:

a11.t 11
some text here
a06.t 06
some text here

위의 예에서는 추출된 처음 두 숫자(첫 번째 패턴과 일치)를 보여주고 줄 끝에 배치합니다(두 번째 패턴).

프로그래밍 언어에서는 파일을 데이터 구조에 로드하고, 편집하고, 바꾸고, 새 파일을 작성했습니다. 그러나 이에 상응하는 한 줄의 코드가 있습니까?

재판:

sed 's/\(a[0-9][0-9].*\)/& \1/I' stack.fa | sed -e 's#a##g2' -e 's#\.\w##g2'

테스트 출력:

a11.t 11
some text here
a06.t 06
some text here

분명히 실험은 효과가 있지만 더 강력한 접근 방식이 있습니까? 또한 이 작업을 더 쉽게 수행할 수 있는 또 다른 텍스트 처리 언어가 있습니까?

답변1

나이에도 불구하고 텍스트 처리 측면에서 Perl과 경쟁할 수 있는 언어는 거의 없습니다. 예를 들어:

  1. 줄 끝에 복사된 숫자 집합만 있다고 가정합니다.

     $ perl -pe 's/.*?a(\d+).*/$& $1/' file
     a11.t 11
     some text here
     a06.t 06
     some text here
    
  2. 여러 개의 숫자 세트, 끝에 두 개를 추가하세요.

     $ cat file
     a11.t
     some text here
     a06.t
     some text here
     a11.t a54.g
    
     $ perl -pe '@nums=(/a(\d+)/g); s/$/ @nums/' file
     a11.t 11
     some text here 
     a06.t 06
     some text here 
     a11.t a54.g 11 54
    

답변2

sed이것은 작업에 완벽한 도구입니다. 그러나 스크립트는 여러 명령으로 구성될 수 있으므로 sed여러 호출을 함께 연결할 필요는 거의 없습니다 .sed

십진수 2자리의 첫 번째 시퀀스를 추출하고 찾은 후 줄 끝에 공백을 추가하려면 다음을 수행할 수 있습니다.

sed 's/\([[:digit:]]\{2\}\).*$/& \1/' < your-file

줄의 두 번째 위치에서 찾은 다음 다음을 따르는 경우에만 이 작업을 수행하려는 경우 a:

sed 's/^a\([[:digit:]]\{2\}\).*$/& \1/' < your-file

이 작업을 원하지 않는 경우 해당 2자리 시퀀스 뒤에 더 많은 숫자가 오는 경우:

sed 's/^a\([[:digit:]]\{2\}\)\([^[:digit:]].*\)\{0,1\}$/& \1/' < your-file

~에 따르면견고성이 질문에 대한 답은 다음과 같습니다.무엇과 짝을 이루어야 할까요?그리고그러면 안되는 것은 무엇입니까?. 그렇기 때문에 요구 사항을 명확하게 지정하고 입력이 어떻게 나타날지 이해하는 것이 중요합니다(예:일치하는 항목을 찾고 싶지 않은 숫자가 행에 있습니까?,입력에 ASCII가 아닌 문자가 포함될 수 있습니까?,입력이 로케일의 문자 세트로 인코딩되어 있습니까?등. ).

위에서 구현에 따라 sed입력은 로케일의 문자 맵( 의 출력 참조 locale charmap)에 따라 텍스트로 디코딩되거나 문자에 해당하는 각 바이트로 해석되며 바이트 0~127은 ASCII 문자 맵( EBCDIC 기반 시스템이 아니라고 가정합니다).

첫 번째 구현 유형 의 경우 sed파일이 올바른 문자 집합으로 인코딩되지 않으면 제대로 작동하지 않을 수 있습니다. 두 번째 범주의 경우 입력에 십진수 인코딩이 포함된 문자가 있으면 실패할 수 있습니다.

답변3

가장 쉬운 방법은 다음과 같습니다.

$ perl -lne '$,=$"; print $_, /a(\d+)/' file
# or this 
$ perl -lpe 's/a(\d+).*\K/ $1/' file
$ awk '
    match($1, /^a[[:digit:]]+/) &&
    gsub(/$/, FS substr($1, RSTART+1, RLENGTH-1)) ||
  1' file

substr참고: 교체 섹션 gsub은 순수 숫자로만 구성되어 있으므로 안전하게 사용할 수 있습니다.

답변4

perl아니면 갈 길이지만 완성을 위해 sed모듈의 일치하는 "그룹" 개념을 사용하여 @PraveenKumarBS의 Python 조각의 첫 번째 버전을 다시 작성합니다.re

#!/usr/bin/python3
import re
pattern = re.compile(r'(\d{2})')
with open('data', 'r') as file:
    for line in file:
        match = re.search(pattern, line)
        if match:
            print(line.rstrip('\n'), match.group(1))
        else:
            print(line.rstrip('\n'))

OP가 찾고 있는 패턴에 항상 첫 글자가 포함되어 있음을 암시하는 것 같으면 패턴을 다음으로 설정하세요 pattern = re.compile(r'[a-zA-Z](\d{2})').

match = re.finditer(pattern, line)한 줄에 여러 개의 일치 항목이 있는 각도(?) 사례는 새로운 일치 표현식과 수정된 지시문(@terdon이 언급한 대로)을 사용하여 쉽게 처리할 수도 있습니다 print.

관련 정보