
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 -n
inperldoc 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 S
ist auch wichtig:
awk '{
split ($6, nums, /S([0-9]+M)?/);
for (i in nums)
if (nums[i] > 16)
{ print; next }
}' test.txt