Как преобразовать список интервалов в список чисел, содержащихся в этих интервалах?

У меня есть большой файл, который выглядит так:

esup_255_3      transdecoder   7655    8192         
esup_6093_1     transdecoder   2732    2774        
esup_25727_1    transdecoder   1       60 
...  

со столбцами 3 и 4, представляющими интервалы чисел.

Я пытаюсь изменить этот файл, чтобы список чисел, содержащихся в интервалах, был указан в другом столбце (здесь, в столбце 5) следующим образом:

esup_255_3      transdecoder    7655    8192    7655     
esup_255_3      transdecoder    7655    8192    7656
esup_255_3      transdecoder    7655    8192    7657 
esup_255_3      transdecoder    7655    8192     ...    
esup_255_3      transdecoder    7655    8192    8192    
esup_6093_1     transdecoder    2732    2774    2732     
esup_6093_1     transdecoder    2732    2774    2733     
esup_6093_1     transdecoder    2732    2774    ....     
esup_6093_1     transdecoder    2732    2774    2774     
... and so on...

Я думаю, что Perl может помочь в этом, но я очень новичок в этом. Я владею только bash, и здесь я не могу найти правильный способ получить то, что мне нужно.

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
0
32
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что-то вроде этого?

    perl -lne 'my ($line, $from, $to) = /^(.*\s(\d+)\s+(\d+)\s*)$/; print "$line\t$_" for $from..$to;' 

Когда я запускаю его на вашем фрагменте, он печатает 641 строку:

esup_255_3      transdecoder   7655    8192             7655
esup_255_3      transdecoder   7655    8192             7656
esup_255_3      transdecoder   7655    8192             7657
[...]
esup_255_3      transdecoder   7655    8192             8190
esup_255_3      transdecoder   7655    8192             8191
esup_255_3      transdecoder   7655    8192             8192
esup_6093_1     transdecoder   2732    2774         2732
esup_6093_1     transdecoder   2732    2774         2733
[...]
esup_6093_1     transdecoder   2732    2774         2773
esup_6093_1     transdecoder   2732    2774         2774
esup_25727_1    transdecoder   1       60   1
esup_25727_1    transdecoder   1       60   2
[...]
esup_25727_1    transdecoder   1       60   59
esup_25727_1    transdecoder   1       60   60

Далее следует объяснение. Начнем с вариантов:

perl -lne

Мы возьмем их справа налево. -e (для «выполнить» или «оценить») просто сообщает Perl, что следующее в командной строке — это код для запуска, поэтому он не будет искать код на стандартном вводе.

-n говорит ему автоматически перебирать ввод построчно; он действует так, как будто вокруг фактического кода обернут цикл while (<>) {...}. Внутри тела цикла текущая строка будет найдена в переменной темы $_.

-l говорит ему удалить символы новой строки из ввода и автоматически добавить их к каждой распечатываемой строке; это в основном убирает новые строки из картины и упрощает логику.

Таким образом, программа будет читать ввод построчно и запускать код, указанный в качестве аргумента для -e, в каждой строке. Давайте посмотрим на этот код, который начинается с этого утверждения:

my ($line, $from, $to) = /^(.*\s(\d+)\s+(\d+)\s*)$/;

Регулярное выражение не имеет явной строки для сопоставления, поэтому оно автоматически сопоставляется с $_, имеющей текущую строку. Он должен соответствовать всей строке (из-за ^ в начале и $ в конце). Фактическое значение строки также захватывается из-за крайних круглых скобок, поэтому это будет первый элемент, возвращаемый совпадением, который назначается переменной $line.

Первая часть строки может быть любой (поскольку .* соответствует всему), поэтому мы действительно смотрим на то, как заканчивается строка, а не на то, как она начинается. Первым интересным элементом является любой пробельный символ (\s), который нужен, чтобы убедиться, что мы не пропустим ни одно из следующих чисел. В частности, мы ищем одну или несколько цифр (\d+), которые заключаются в круглые скобки, поэтому это значение также будет возвращено при совпадении; это второй захват, поэтому он входит во вторую переменную в присваивании, $from. После этих цифр мы ищем еще пробелы (требуется хотя бы один пробел, но допускается любое число), за которым следует еще одна последовательность цифр; этот второй набор цифр снова захватывается и возвращается, поэтому он оказывается в последней переменной $to. Наконец, мы разрешаем за последним набором цифр следовать любое количество необязательных завершающих пробелов.

Итак, после прочтения вашей первой строки, $_ = "esup_255_3 transdecoder 7655 8192 ", совпадение + присваивание установит $line на копию всей этой строки, $from на 7655 и $to на 8192.

Затем подходим к выходу. Эта строка:

print "$line\t$_" for $from .. $to;

Более короткий способ записи этого цикла:

foreach $_  ($from .. $to) {
   print "$line\t$_";
}

Это означает, что он перебирает целые числа от $from до $to, повторно используя $_ в качестве управляющей переменной цикла (поэтому нам пришлось скопировать текущую строку в $line). Для каждого значения в диапазоне выводится копия всей строки, за которой следует табуляция и текущий номер.

Другие вопросы по теме