Подсчитайте самый длинный участок последовательных шаблонов

Установите сценарий оболочки, описанный здесь: coupure shell script. Это разновидность ping, сделанная менее многословной и более умной.

После установки используйте его параллельно для обнаружения падений на вашем провайдере (например, используйте один из его DNS-серверов, который должен иметь максимальную связность) и в Интернете за вашим провайдером (например, используйте один из серверов Google).

Благодаря этой параллельной работе вы сможете узнать, есть ли у вас проблемы с доступом к провайдеру или к Интернету за ним.

4
29.06.2018, 12:48
5 ответов

FWIW вот способ сделать это на Perl, используя maxизList::Util

$ perl -MList::Util=max -lpe '$_.= " ". max 0, map length, /[CT]+/gi' file
CACCGTTGCCAAACAATG 2
TTAGAAGCCTGTCAGCCT 3
CATTGCTCTCAGACCCAC 5
GATGTACGTCACATTAGA 2
ACACGGAATCTGCTTTTT 6
CAGAATTCCCAAAGATGG 5
5
27.01.2020, 20:46

Более быстрое решение GNUawk:

awk -v FPAT='[ctCT]+' \
'{ 
     max_l = t_len = 0;
     for (i=1; i <= NF; i++) {
         len = length($i);
         if (len > max_l) max_l = len;
         t_len += len
     }
     print $0, t_len, max_l
 }' inputfile

Выход:

CACCGTTGCCAAACAATG 9 2
TTAGAAGCCTGTCAGCCT 10 3
CATTGCTCTCAGACCCAC 12 5
GATGTACGTCACATTAGA 8 2
ACACGGAATCTGCTTTTT 11 6
CAGAATTCCCAAAGATGG 7 5

Сравнение производительности по времени (тест inputfileсодержит около 120000 строк):

$ time awk -v FPAT='[ctCT]+' '{ max_l = t_len = 0; for (i=1; i <= NF; i++) { len = length($i); if (len > max_l) max_l = len; t_len += len } print $0, t_len, max_l }' inputfile > /dev/null

real    0m1.018s
user    0m0.948s
sys 0m0.012s

$ time awk '{ split($0, a, "[^CTct]+"); m=0; for (i in a) { len=length(a[i]); if (len > m) m=len } print $0, m }' inputfile > /dev/null

real    0m1.802s
user    0m1.688s
sys 0m0.028s

$ time perl -MList::Util=max -lpe '$_ = "$_ ". max map { length $_ } /[CT]*/gi' inputfile > /dev/null

real    0m1.216s
user    0m1.160s
sys 0m0.016s

$ time sed 'h;y/cCtT/xxxx/;x;H;s/./x/g;G; s/^\(x*\).*\n.*\1.*\n/\1 /; s/^x\{10\}/1/;s/$/:9876543210xxxxxxxxx/; s/^\(1*\)\(x*\) \(.*\):.*\(.\).\{9\}\2$/\3 \1\4/' inputfile > /dev/null

real    1m4.165s
user    1m2.784s
sys 0m0.352s
3
27.01.2020, 20:46

Сsed(предполагается не более 19 символов в строке ), просто для удовольствия и с использованием жадных свойств сопоставления RE:

sed '
  h;y/cCtT/xxxx/;x;H;s/./x/g;G
  s/^\(x*\).*\n.*\1.*\n/\1 /
  s/^x\{10\}/1/;s/$/:9876543210xxxxxxxxx/
  s/^\(1*\)\(x*\) \(.*\):.*\(.\).\{9\}\2$/\3 \1\4/'

Вариант решения @Kusalananda:

awk -F '[^cCtT]+' '
  {
    max = 0
    for (i = 1; i <= NF; i++)
      if ((l = length($i)) > max)
        max = l
    print $0, max
  }'
3
27.01.2020, 20:46

Попробуйте также

awk '
        {T0 = $0
         while (match (T0, /[CTct]+/))  {if (RLENGTH > MX) MX = RLENGTH
                                         T0 = substr (T0, RSTART+RLENGTH)
                                        }
         print $0, MX
        }
' file

сроки немного быстрее, чем другие awkпредложения.

0
27.01.2020, 20:46
$ awk '{ split($0, a, "[^CTct]+"); m=0
         for (i in a) {
             len=length(a[i])
             if (len > m) m=len
         }
         print $0, m  }' file
CACCGTTGCCAAACAATG 2
TTAGAAGCCTGTCAGCCT 3
CATTGCTCTCAGACCCAC 5
GATGTACGTCACATTAGA 2
ACACGGAATCTGCTTTTT 6
CAGAATTCCCAAAGATGG 5

Эта awkпрограмма разбивает каждую строку на прогоны всего, что не является ни верхним, ни нижним регистром Cили T. Затем он перебирает биты, полученные в результате разделения, и находит самый длинный. Затем он печатает исходную строку вместе с найденной максимальной длиной.

Поскольку Роман рассматривал тайминги для различных решений, вот более быстрое решение:

awk -F "[^CTct]+" '
    m = 0
    for (i = 1; i <= NF; ++i) {
        len = length($i)
        if (len > m) m = len
    }
    print m' file | paste file -

Это быстрее, поскольку разделяет строки только один раз. Первый код дополнительно пытается разбить входные строки по пробелам.

Синхронизация с использованием mawkпоказывает 0,79 с на 500 000 строк. Первое решение использует 1,69 с для тех же данных, показывая, что это вероятно операция разделения, которая занимает больше всего времени.

4
27.01.2020, 20:46

Теги

Похожие вопросы