Filtern einer Datei anhand einer Zeichenfolge

Filtern einer Datei anhand einer Zeichenfolge

Ich habe eine Datei, die so aussieht

a   0   gene1   56  0   6S32M12S    *
b   256 gene2   56  0   6S32M12S    *
c   256 gene3   55  0   6S27M17S    *
d   16  gene4   110 9   19S25M6S    *
e   272 gene5   141 9   23S21M6S    *
f   272 gene6   139 9   24S20M6S    *
g   0   gene7   38  1   6S44M   *
h   256 gene8   38  1   6S44M   *
I   256 gene9   38  1   6S44M   *
j   256 gene10  40  1   8S42M   *

Die 6. Spalte ist die Zeichenfolge, nach der ich filtern möchte. Wenn die Zeichenfolge eine Übereinstimmung gleich oder größer als 16S enthält (also sagen wir 16S, 17S, 18S, 19S und mehr), werden diese Zeilen gemeldet. Wie kann ich das tun? Die Ausgabe für das obige Beispiel wäre:

c   256 gene3   55  0   6S27M17S    *
d   16  gene4   110 9   19S25M6S    *
e   272 gene5   141 9   23S21M6S    *
f   272 gene6   139 9   24S20M6S    *

Ich habe Ihnen nur einen kleinen Ausschnitt aus einer großen Datei gezeigt.

Antwort1

perl -ane 'print if grep {$_ >= 16} ($F[5] =~ /(\d+)S/g)' file

Ausgänge

c   256 gene3   55  0   6S27M17S    *
d   16  gene4   110 9   19S25M6S    *
e   272 gene5   141 9   23S21M6S    *
f   272 gene6   139 9   24S20M6S    *

Dadurch werden alle Ziffern gefunden, denen im 6. Feld ein "S" folgt. Wenn eine davon größer oder gleich 16 ist, wird die Zeile gedruckt.


Suchen Sie -ninperldoc perlrun

Eine coole Möglichkeit zu sehen, was Perl mit einem Einzeiler macht, ist die Option-MO=Deparse

$ perl -MO=Deparse -ane 'print if grep {$_ >= 16} ($F[5] =~ /(\d+)S/g)'
LINE: while (defined($_ = <ARGV>)) {
    our(@F) = split(' ', $_, 0);
    print $_ if grep {$_ >= 16;} $F[5] =~ /(\d+)S/g;
}
-e syntax OK

sehen
http://perldoc.perl.org/B/Deparse.html
http://perldoc.perl.org/O.html

Ich werde es erklären, indem ich den Einzeiler zu einem Skript erweitere:

#!/usr/bin/env perl
my $filename = shift @ARGV;
open my $fh, '<', $filename or die $!;
while (defined($_ = <$fh>)) {
    my @F = split(' ', $_, 0);
    my @s_numbers = $F[5] =~ /(\d+)S/g;
    if (grep {$_ >= 16;} @s_numbers) {
        print $_;
    }
}
close $fh;

Antwort2

Angenommen, der zweite Punkt Sist auch wichtig:

awk '{
split ($6, nums, /S([0-9]+M)?/); 
for (i in nums) 
  if (nums[i] > 16) 
    { print; next }
}' test.txt

verwandte Informationen