일치하는 패턴을 편집한 다음 다른 패턴을 편집된 패턴으로 바꾸는 방법이 있습니까?
입력하다:
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과 경쟁할 수 있는 언어는 거의 없습니다. 예를 들어:
줄 끝에 복사된 숫자 집합만 있다고 가정합니다.
$ perl -pe 's/.*?a(\d+).*/$& $1/' file a11.t 11 some text here a06.t 06 some text here
여러 개의 숫자 세트, 끝에 두 개를 추가하세요.
$ 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
.