
次のようなファイルがあります
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 *
6 列目は、フィルター処理する文字列です。基本的に、文字列に 16S 以上の一致 (つまり、16S、17S、18S、19S など) が含まれている場合は、それらの行を報告します。どうすればよいでしょうか。上記の例の出力は次のようになります。
c 256 gene3 55 0 6S27M17S *
d 16 gene4 110 9 19S25M6S *
e 272 gene5 141 9 23S21M6S *
f 272 gene6 139 9 24S20M6S *
大きなファイルから抜粋した小さなスニペットをお見せしました。
答え1
perl -ane 'print if grep {$_ >= 16} ($F[5] =~ /(\d+)S/g)' file
出力
c 256 gene3 55 0 6S27M17S *
d 16 gene4 110 9 19S25M6S *
e 272 gene5 141 9 23S21M6S *
f 272 gene6 139 9 24S20M6S *
これにより、6 番目のフィールドで「S」が続くすべての数字が検索されます。16 以上の場合は、その行が出力されます。
探す-n
perldoc perlrun
Perlがワンライナーで何をしているかを見るためのクールな方法の1つは、オプションを追加することです。-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
見る
http://perldoc.perl.org/B/Deparse.html
翻訳元:
ワンライナーをスクリプトに拡張して説明します。
#!/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;
答え2
2 番目S
も重要であると仮定します。
awk '{
split ($6, nums, /S([0-9]+M)?/);
for (i in nums)
if (nums[i] > 16)
{ print; next }
}' test.txt