목록에 문자열이 있는지 확인하고 문자열이 있으면 세 번째 파일을 출력합니다.

목록에 문자열이 있는지 확인하고 문자열이 있으면 세 번째 파일을 출력합니다.

2개의 파일("data.tab" 및 "mylist.tab")이 있습니다.

내 "data.tab" 파일은 다음과 같습니다:

Info_1    abc1     abc2     abc3
Info_2    abc5     ghi4
Info_3    abc10
Info_4    abc8     abc7     abc87    klm78    abc99
Info_5    

내 "mylist.tab" 파일은 다음과 같습니다:

abc2
abc10
abc34
abc99
abc78
abc8
abc3
abc5
abc4

"data.tab"(열 1 제외)의 각 문자열이 "mylist.tab"에 있는지 검색하고 싶습니다. 문자열이 있으면 해당 행/열에 "1"을 포함하고 그렇지 않으면 "0"을 포함하는 세 번째 파일 "output.tab"을 만들고 싶습니다.

예: "output.tab"

Info_1   0    1     1
Info_2   1    0
Info_3   1
Info_4   1    0     0    0    1
Info_5   

"data.tab"에는 각 행마다 다른 수의 열이 포함되어 있습니다.

답변1

이는 awk로 간단하게 표현됩니다.

awk 'FNR==NR { h[$1]; next } { for(i=2; i<=NF; i++) $i = ($i in h)? 1 : 0 } 1' mylist.tab data.tab

또는 더 읽기 쉬운 형식으로:

파싱.awk

# Collect mylist.tab into the `h` associative array
FNR==NR {
  h[$1]
  next
}

# For all but the first column in data.tab check and record if it is in `h`
{ 
  for(i=2; i<=NF; i++) 
    $i = ($i in h) ? 1 : 0 
}

# Short for { print $0 }
1

다음과 같이 실행하세요:

awk -f parse.awk mylist.tab data.tab

산출:

Info_1 0 1 1
Info_2 1 0
Info_3 1
Info_4 1 0 0 0 1
Info_5

또는 탭으로 구분된 열의 ​​경우:

awk -v OFS='\t' -f parse.awk mylist.tab data.tab

산출:

Info_1  0   1   1
Info_2  1   0
Info_3  1
Info_4  1   0   0   0   1
Info_5

답변2

펄을 구출해주세요!

목록 요소를 해시에 저장한 다음 테이블을 읽고 공백으로 분할한 다음 해시를 확인하여 0 또는 1을 인쇄합니다.

#!/usr/bin/perl
use warnings;
use strict;

my %in_list;
open my $LIST, '<', 'mylist.tab' or die $!;
while (<$LIST>) {
    chomp;
    $in_list{$_} = 1;
}

open my $TAB, '<', 'data.tab';
while (<$TAB>) {
    my @cells = split;
    print shift @cells, "\t";
    print join "\t", map $in_list{$_} ? 1 : 0, @cells;
    print "\n";
}

답변3

mylist.tab에서 스크립트를 sed생성 하고 data.tab에서 실행하는 데 사용합니다 .sed

sed \
    -e '1i s/^[ \\t]*//' \
    -e 's@\(.*\)@s/\\([ \\t]\\)\1\\b/\\11/@g' \
    -e '$as/\\([ \\t]\\)[^ \\t]\\{2,\\}\\b/\\10/g' mylist.tab \
    > /tmp/x.sed 
sed -f /tmp/x.sed data.tab

참고 "mylist.tab"의 모든 문자열에는 최소 2개의 문자가 있다고 가정합니다.

답변4

또 다른 perl솔루션

$ perl -lne 'if(!$#ARGV){ $h{$_}=1 }
             else{ s/\h\K\H+/$h{$&} ? 1 : 0/ge; print }
            ' mylist.tab data.tab
Info_1    0     1     1
Info_2    1     0
Info_3    1
Info_4    1     0     0    0    1
Info_5    
  • if(!$#ARGV){ $h{$_}=1 }단어 해시를 구축하세요mylist.tab
  • s/\h\K\H+/$h{$&} ? 1 : 0/ge에 있는 줄의 경우 해시 변수에 있으면 else data.tab로 바꿉니다 . 공백이 있는지 확인하는 긍정적인 탐색이므로 첫 번째 열이 일치하지 않습니다 .10\h\K
  • 그런 다음 수정된 줄을 인쇄합니다.

관련 정보