한 줄에 2개의 서로 다른 패턴을 문자열로 인쇄합니다.

한 줄에 2개의 서로 다른 패턴을 문자열로 인쇄합니다.

다음과 같은 문자열이 포함된 파일이 있습니다.

F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315

문자열은 토큰(이 경우 "F"와 숫자)으로 구분됩니다. 이 경우 레이블은 F1, F2, F3, F4, F5F6입니다 F7.

F2다음 5자 와 다음 6자를 F6공백으로 구분하여 인쇄하고 싶습니다.

B3094 BC313D

한 줄이 아닌 두 줄로 인쇄되지만 여기에 내 시도가 있습니다. 두 값을 한 줄에 넣는 방법.

$ echo F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315 | \
   awk '{match($0,/F2/); print substr($0, RSTART +2, RLENGTH +3);} \
        {match($0,/F6/); print substr($0, RSTART +2,RLENGTH +4);}'

답변1

실행 가능한 솔루션에 매우 가깝습니다. 다음은 한 가지 접근 방식입니다(가독성을 위해 형식화됨).

awk '{
    match($0,/F2/); 
    a=substr($0, RSTART +2, RLENGTH +3); 
    match($0,/F6/); 
    b=substr($0, RSTART +2,RLENGTH +4);
    print a" "b
}'

substr()이 예에서는 직접 인쇄하는 대신 두 함수를 변수에 할당한 다음 마지막에 동시에 인쇄하도록 설정하겠습니다. 단일 인쇄 호출로 인쇄하면 awk줄의 각 부분 뒤가 아닌 줄 끝에 개행만 추가되므로 결과가 두 줄로 분할됩니다.

bash:~$ echo F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315 | awk '{match($0,/F2/); a=substr($0, RSTART +2, RLENGTH +3); match($0,/F6/); b=substr($0, RSTART +2,RLENGTH +4); print a" "b}'
B3094 BC313D

답변2

마커가 순서대로 지정되어 있다는 것을 알고 있으면 이를 필드 구분 기호로 사용할 수 있습니다.Fn

echo 'F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315' | 
    awk -F'(F2|F6)' '{print substr($2,1,5), substr($3,1,6)}'
B3094 BC313D

또는 모든 태그를 분할하고 그에 따라 필드 번호를 매깁니다.Fn

echo 'F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315' | 
    awk -F'F[0-9]' '{print substr($3,1,5), substr($7,1,6)}'
B3094 BC313D

(이 경우 substr다음 항목의 모든 내용을 원할 경우 전혀 필요하지 않을 수 있습니다. 문제 설명에서 명확하지 않습니다.)Fn

GNU Awk를 사용하면 단일 패턴으로 두 개의 하위 문자열을 캡처하고 match선택적 배열을 통해 액세스할 수 있습니다.

echo 'F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315' | 
    gawk 'match($0, /F2(.{5}).*F6(.{6})/, a) {print a[1], a[2]}'
B3094 BC313D

또는 Perl을 사용하여 토큰 뒤의 문자에 대한 LookBehind 캡처를 사용할 수 있습니다.

echo 'F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315' | 
    perl -lne 'print join " ", /(?<=F2).{5}|(?<=F6).{6}/g'
B3094 BC313D

또는

echo 'F1B308F2B3094F3B310F4B317CF5B312F6BC313DF7B315' | 
    perl -lne 'print "$1 $2" if /(?<=F2)(.{5}).*?(?<=F6)(.{6})/g'
B3094 BC313D

답변3

perl -lne ' $, = $"; print /(?=.*F2(.{5}))(?=.*F6(.{6}))/' input-file.txt

현재 레코드의 이전에 나타나는 것이 무엇이든 F2위 의 숫자는 다음 숫자를 인쇄합니다 .F6F2F6

$, = OFS $" = double quoted separator = single space

관련 정보