문자열 인덱스 처리

문자열 인덱스 처리

내 입력 파일은 다음과 같습니다.

#key    string              pos(string)     
key1    AA000AA000000AAA0A  2, 3, 18, 12    
key2    00A00AAA000AAAA00A  3, 18           

각 키 행 끝에 새 열(탭으로 구분)을 추가하고 싶습니다. 입력 파일의 열 2에 가 있으면 A새 열에는 입력 파일의 열 3에 지정된 위치가 포함됩니다. 입력 파일의 열 2에 a가 있는 경우 0해당 위치는 새 열에 인쇄되어서는 안 됩니다.

기본적으로 이것은 원하는 출력입니다.

#key    string              pos(string)     Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18           3, 18

간단한 설명:
(키 1)

  • 인덱스 2의 문자열은 새 열에 A-> 항목을 추가합니다.2
  • 인덱스 3의 문자열에는 0-> 항목이 있습니다.3 아니요새 열에 추가
  • 인덱스 12의 문자열에는 0-> 항목이 있습니다.12 아니요새 열에 추가
  • 인덱스 18의 문자열은 새 열에 A-> 항목을 추가합니다.18

저는 Python으로 이 작업을 수행하고 있지만 여러 개의 키와 항목(문자열을 처리하기에는 꽤 깁니다)이 붙어 있어서 명령줄(더 가벼운) 솔루션에 대한 조언을 구해야겠다고 생각했습니다.

내 의견은 다음과 같습니다.

  • pos(string) 필드를 분할하여 문자열 필드에서 검색 중인 인덱스를 가져옵니다.
  • 문자열의 특정 인덱스에 있는 문자를 가져옵니다.
  • 진술서(?)

답변1

다음 스크립트는 어떻습니까 awk?

#!/usr/bin/awk -f
BEGIN {
        FS="\t"
        print "#key\tstring\tpos(string)\tApos(string)"
}

{
        out=""
        printf "%s\t",$0
        split($2,str,"")
        gsub(/ /,"",$3)
        split($3,pos,",")
        for (i in pos){
                if (str[pos[i]]=="A"){
                        out = out pos[i] ", "
                }
        }
        gsub(/, $/,"",out)
        print out
}

예를 들어 다른 이름으로 저장 findA.awk하고 실행 가능하게 만듭니다 chmod +x findA.awk.

그런 다음 입력 데이터에 대해 실행하고 출력을 새 파일로 리디렉션합니다.

./findA.awk input.txt > output.txt
cat output.txt
#key    string  pos(string) Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18   3, 18

출력은 요구 사항에 따라 탭으로 구분되어 있고 탭 너비가 다양한 문자열의 너비와 일치하지 않기 때문에 예제만큼 깔끔하지 않습니다.

답변2

지금은 어떻게 했는지 잘 모르겠지만(Python 코드를 살펴보는 것이 도움이 될 것입니다) 다음과 같이 열 2의 "A"를 가리키는 열 3 요소 목록을 만들 수 있습니다.

[i for i in COLUMN3 if COLUMN2[i]=='A']

이것은 간단한 질문처럼 보이지만 아마도 완전히 이해하지 못할 수도 있습니다. 문자열이 반복 가능하다는 사실을 잊었나요?

답변3

끔찍한 것 perl:

$ perl -anle '
    printf "%s    Apos(string)\n",$_ and next if /^#/;
    printf "%s",$_;
    $len = 12 - length((split(/\s+/,$_,3))[-1]);
    for $pos_ss (@F[2..$#F]) {
        $char = substr($F[1],int($pos_ss)-1,1);
        push @res, int($pos_ss) if $char eq 'A';
    }
    printf "%@{[12-4+$len]}s\n", join ", ",@res;
    @res=();
' file
#key    string              pos(string)    Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12   2, 18
key2    00A00AAA000AAAA00A  3, 18          3, 18

내 솔루션과 유사하게 작동합니다.이 답변, 그리고 $len인쇄된 마지막 열을 정렬하는 데 필요한 형식을 계산하는 변수를 추가합니다.

관련 정보