마지막 열이 동일해야 하는 텍스트 파일의 연속된 줄을 비교하는 방법은 무엇입니까? 그리고 두 번째 열의 값 중 하나 이상이 일치하지 않아야 합니다.
- 일치하는 항목이 있으면 먼저 파일의 열 6을 비교하세요.
- 그런 다음 열 4에서 일치하는 행을 비교합니다. 4열의 모든 값은 동일해서는 안 되며, 적어도 하나의 값은 달라야 합니다. 여기서 HSF1과 HIF1AN은 라인 1, 2, 3에 위치합니다.
입력 파일
chr10 102979 103832 HSF1 305
chr10 102979 103832 HIF1AN 1 305
chr10 102979 103832 HSF1 305
chr10 103124438 103124851 HSF1 471
chr10 103124438 103124851 EGLN1 2 471
chr10 103969896 103970503 HSF1 472
chr10 103969896 103970503 HSF1 472
chr10 39135037 39142175 HSF1 335
chr10 4191461 4191936 HSF1 309
chr10 4191461 4191936 HSF1 309
chr10 42423355 42424014 HSF1 336
결과물 파일
chr10 102979 103832 HSF1 305
chr10 102979 103832 HIF1AN 1 305
chr10 102979 103832 HSF1 305
chr10 103124438 103124851 HSF1 471
chr10 103124438 103124851 EGLN1 2 471
답변1
탭으로 구분된 파일을 가정하면 GNU awk를 사용할 수 있습니다.
gawk -F'\t' 'NR == FNR {count[$6][$4]++; next} length(count[$6]) > 1' file file
chr10 102979 103832 HSF1 305
chr10 102979 103832 HIF1AN 1 305
chr10 102979 103832 HSF1 305
chr10 103124438 103124851 HSF1 471
chr10 103124438 103124851 EGLN1 2 471
이는 파일을 두 번 통과합니다. 첫 번째는 각 $6에 대해 몇 개의 $4 값이 발생하는지 계산하고, 두 번째는 해당 $6에 대해 두 개 이상의 $4 값이 있는 경우 레코드를 출력합니다.
단일 패스로 수행하는 것이 가능할 수도 있지만 복잡성, 메모리 사용량 및 원래 순서 손실 가능성이 있습니다.
Perl의 동일한 논리
perl -Mautodie -e '
open $f, "<", shift;
while (<$f>) {
@F = split /\t/;
$c{ $F[5] }{ $F[3] }++;
}
# re-process the file
seek $f, 0, 0;
while (<$f>) {
@F = split /\t/;
print if scalar keys %{ $c{$F[5]} } > 1;
}
' file
답변2
파일을 한 줄씩 읽고, 마지막 열의 값이 버퍼의 다른 모든 줄과 동일한 경우 해당 줄을 버퍼에 저장하고, 그렇지 않으면 버퍼를 처리하여 비웁니다.
버퍼를 처리한다는 것은 네 번째 열 값을 공유하지 않는 최소한 한 쌍의 연속 행을 찾고 성공하면 버퍼를 인쇄하는 것을 의미합니다.
더 나은 출력을 얻고 값에 더 쉽게 액세스하기 위해 개별 열과 함께 정확한 행을 버퍼에 저장합니다.
#!/usr/bin/perl
use warnings;
use strict;
sub process {
my (@rows) = @_;
my $different;
for my $i (1 .. $#rows) {
$different = 1, last if $rows[ $i - 1 ][4] ne $rows[$i][4];
}
print map "$_->[0]\n", @rows if $different;
}
my @buffer;
while (<>) {
chomp;
my @columns = split;
if (! @buffer || $buffer[0][-1] == $columns[-1]) {
push @buffer, [$_, @columns];
} else {
process(@buffer);
@buffer = [$_, split];
}
}
process(@buffer);