![목록에 문자열이 있는지 확인하고, 문자열이 있으면 세 번째 파일을 출력합니다.](https://linux55.com/image/97245/%EB%AA%A9%EB%A1%9D%EC%97%90%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B4%20%EC%9E%88%EB%8A%94%EC%A7%80%20%ED%99%95%EC%9D%B8%ED%95%98%EA%B3%A0%2C%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B4%20%EC%9E%88%EC%9C%BC%EB%A9%B4%20%EC%84%B8%20%EB%B2%88%EC%A7%B8%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EC%B6%9C%EB%A0%A5%ED%95%A9%EB%8B%88%EB%8B%A4..png)
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"의 모든 문자열(첫 번째 열 제외)이 "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
Perl이 구출하러 옵니다!
목록 요소를 해시에 저장한 다음 테이블을 읽고 공백으로 분할한 다음 해시를 확인하여 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
의 행에 대해data.tab
해시1
변수에 있으면 로 바꾸고, 그렇지 않으면 로 바꿉니다0
. 공백이 있는지\h\K
적극적으로 되돌아보고 첫 번째 열 일치를 피하십시오.- 그런 다음 수정된 줄을 인쇄합니다.