세미콜론으로 구분된 여러 열의 데이터를 필터링하는 방법

세미콜론으로 구분된 여러 열의 데이터를 필터링하는 방법

세미콜론으로 구분된 데이터가 포함된 3개의 열이 있는 탭으로 구분된 파일이 있습니다. (3개 열의 3가지 조건을 모두 만족하는) 각 열의 값을 필터링하고 싶습니다: 1번째 열(<-0.5), 2번째 열(>1), 3번째 열(>2). 실제 데이터에는 여러 열이 있습니다.

입력하다

-0.6;0.14;-0.56;0.2    10.4;NA;5.1;2    3;1;4;3    A;B;C;D
-0.9;-0.16;-1.1        2.4;0.1;0.9      10;1;3     E;F;G 

원하는 출력

-0.6;-0.56         10.4;5.1       3;4    A;C
-0.9               2.4            10     E

각 행에 대해 각 열의 값 개수는 필터링 전과 후가 동일해야 합니다.

답변1

여기 Perl에 관한 미친 것들이 있습니다.

perl -lane '
    BEGIN {
        @criteria = (
            sub {shift() < -0.5},
            sub {shift() > 1},
            sub {shift() > 2},
        )
    }
    @filtered = ();
    for $i (0..$#F) {
        push @filtered, join ";", grep {$criteria[$i]->($_)} split /;/, $F[$i];
    }
    print join " ", @filtered;
' file | column -t
-0.6;-0.56  10.4;5.1  3;4
-0.9        2.4       10

이는 귀하의 요구 사항을 더 정확하게 반영합니다.

perl -lane '
    sub criteria {
        $_[0] < -0.5 and
        $_[1] > 1    and
        $_[2] > 2
    }

    @data = map {[split /;/]} @F;
    @filtered = map {[]} @F;

    for ($i = 0; $i < @{$data[0]}; $i++) {
        @tuple = map {$data[$_][$i]} (0..$#F);
        if (criteria(@tuple)) {
            push @{$filtered[$_]}, $tuple[$_] for (0..$#F);
        }
    }
    print join " ", map {join ";", @$_} @filtered;
' file

답변2

통과하다 awk:

  • 처음 세 필드가 모든 컬렉션 구성원에 대한 기준을 충족하는지 테스트합니다. (필드를 분할 ;하고 각 쌍을 테스트)

  • 그렇다면 각 필드에서 컬렉션이 어디에 있는지 기억하세요. (배열에서 sel)

  • 두 번째 블록에서는 모든 필드를 반복하고 이전 위치와 일치하는 값만 유지합니다.

  • 일치하는 항목이 있으면 인쇄하세요.

    BEGIN {FS=OFS="\t"}
    {
    #select IDs of value sets to be keept
      split($1,a,";")
      split($2,b,";")
      split($3,c,";")
      nsel=0 ; delete sel
      for ( i in a ) {
          if (a[i]+0<-0.5 && b[i]+0>1 && c[i]+0>2) {
          sel[++nsel]=i
          }
      }
    #if any: run through all fields and reselect
      if (nsel) {
          for (i=1 ; i<=NF ; i++) {
              split($i,a,";")
              $i=a[sel[1]]
              for (j=2 ; j<=nsel ; j++) {
                  $i=$i";"a[sel[j]]
              }
          }
      }
    }
    #print only if any matching set was found
    nsel
    

관련 정보