열의 패턴으로 시작하는 정보만 선택하고 다른 열에 인쇄하는 방법

열의 패턴으로 시작하는 정보만 선택하고 다른 열에 인쇄하는 방법

데이터 파일이 있습니다 A.tsv(필드 구분 기호 = \t).

id  clade   mutation
243 40A S:ojo,L:juju,S:lili
254     
267 40B J:jijy,S:asel,M:ase

다음과 같이 다른 열(새 파일 B.tsv)에 로 시작하는 돌연변이만 인쇄하고 싶습니다 .S:

id  clade   mutation    S_mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254     
267 40B J:jijy,S:asel,M:ase S:asel

awk로 몇 가지 명령을 시도했지만 결과가 없습니다.

awk -F '\t' 'BEGIN { OFS = FS } NR==1 {$(NF+1)="S_Mutation"} ; NR != 1 { $4 = ($3==^[Ss] ? $4 ) }; 1' A.tsv > B.tsv

무엇을 해야할지 아시나요? 감사해요

답변1

이를 통해 POSIX awk그림과 같이 작동할 수 있습니다. 쉼표가 있는 세 번째 필드를 1보다 큰 행으로 분할하고 S:로 시작하는 요소를 선택한 다음 쉼표로 연결하여 마지막 +1 필드로 만듭니다.

awk -F '\t' '
  BEGIN {
    OFS = FS
    _SEP_ = ","
  }

  NR==1{$(NF+1) = "S_mutation"}

  NR>1&&length($3)>0{
    nf = split($3, a, _SEP_)
    t = ""
    for (i=1; i<=nf; i++) {
      if (a[i] ~ /^S:/) {
        t = t (t=="" ? t : _SEP_) a[i]
      }
    }
    $(NF+1) = t
  }1
' file

똑같지만 Perl정규식을 사용하면

perl -lnse '$,="\t";
  print $_,($.==1?q(S_mutation):
  "@{[/(?:\t|,)\KS:[^,]*/g]}"||());
' -- -\"=, ./file

산출:

id   clade  mutation             S-mutation
243  40A    S:ojo,L:juju,S:lili  S:ojo,S:lili
254                              
267  40B    J:jijy,S:asel,M:ase  S:asel

답변2

(POSIX)를 사용하세요 awk.

awk -F "\t" '
BEGIN   { OFS = FS }
NR == 1 { $4 = "S_Mutation" }
NR  > 1 && NF == 3 {
    printf "%s", $0 "\t"
    $0 = $3
    gsub(/[^S]:[^,]*,?/, "")
    sub(/,$/, "")
    print $1
    next
}
1' data.txt
  • 행 > 1이고 필드 수 = 3인 경우
    • 줄 바꿈 없이 줄을 인쇄합니다.
    • 행 설정 = 필드 3
    • 다음 문자로 시작하지 않는 문자열을 제거합니다.S:
    • 모든 후행 쉼표를 제거하세요.
    • 줄 바꿈이 있는 필드 인쇄
    • 다음 줄 처리
  • 기타
    • 인쇄 라인

$1후행 탭을 인쇄하고 교체 후에 아무 것도 없는지 테스트한 다음 TAB+ 필드를 인쇄하고 싶지 않을 것입니다 . (필드가 없는 행에 후행 탭을 원하지 않는 경우 S:xxx. 예:

    # Print line
    printf "%s", $0
    # Set line = field 3
    $0 = $3
    # Replace all N:xxx where N is not S
    gsub(/[^S]:[^,]*,?/, "")
    # Remove trailing comma
    sub(/,$/, "")
    # Print the field
    if ($1 != "")
        print "\t"$1
    else
        print ""
    # Continue with next line
    next

답변3

펄 사용하기

perl -F'\t' -lpe '
    push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
    $_ = join "\t", @F
' A.tsv > B.tsv

전임자.

$ perl -F'\t' -lpe '
    push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
    $_ = join "\t", @F
' A.tsv | column -t
id   clade  mutation             S_mutation
243  40A    S:ojo,L:juju,S:lili  S:ojo,S:lili
254
267  40B    J:jijy,S:asel,M:ase  S:asel

답변4

사용해도 괜찮다면 다음을 사용하세요 sed.

sed 'h;s/.*[[:space:]]/,/;s/,[^S]:[^,]*//g;x;G;s/\n,/\t/'

\tGNU에서만 작동 합니다 sed. 다른 스타일의 경우 ctrlv일반적으로 텍스트 탭은 입력한 다음 Tab 키를 눌러 삽입됩니다.

개념은 행을 예약된 공간에 유지한 다음 마지막 열을 격리하고 변형을 제외한 모든 것을 제거하는 것입니다 S:. 그런 다음 저장된 행의 마지막 열로 추가합니다.

  • h해당 줄을 예약된 공간에 복사하세요.
  • s/.*[[:space:]]/,/마지막 탭이나 공백 앞의 모든 내용을 쉼표로 바꾸십시오. 따라서 마지막 열을 유지하고 앞에 쉼표를 추가하십시오. 이 쉼표는 다음 단계에서 도움이 될 것입니다
  • s/,[^S]:[^,]*//gS:제외한 모든 요소를 ​​제거합니다.
  • x보관 공간과 패턴 공간을 교환하여 G보관 공간에 유지된 원래 열에 새 열이 추가되도록 합니다.
  • s/\n,/\t/마지막으로 탭을 통해 도입한 추가 개행 문자와 쉼표를 대체합니다.

관련 정보