Вот как я понял вашу проблему:
Входные данные представляют собой текстовый файл из нескольких строк, по пятнадцать чисел в каждой строке, разделенных пробелами или табуляциями. В некоторых строках (возможно, в последней) может быть меньше пятнадцати чисел. (Фактически, в приведенном ниже решении не имеет значения, сколько чисел находится в каждой строке.)
Вы должны сгруппировать числа в наборы по 129 чисел в каждом, последовательно. Последняя группа может иметь менее 129 номеров, если количество входных данных не является точным кратным 129. В приведенном ниже решении не имеет значения, сколько входных номеров имеется (и, следовательно, сколько групп будет в выходных данных). ).
Для каждой группы из 129 номеров вы должны получить несколько строк на выходе. Сначала заголовок или метка, в которой написано [Lipid n]
, где n
- номер строки, а затем числа в этой группе, показанные по пятнадцать в каждой строке (так, будет восемь полных строк и девятая строка только с 9 цифрами на строке). it: 129 = 15 * 8 + 9).
Вот как это можно сделать. Сначала давайте начнем с небольшого примера, а затем мы сможем посмотреть, что нужно изменить для более общего решения.
Я предполагаю, что ваши входные данные могут быть произвольными числами любой длины; конечно, если это последовательные числа, как вы показали в своих выборочных данных, тогда проблема тривиальна и совершенно неинтересна. Итак, давайте предположим, что ваши числа на самом деле вообще любые числа. (Не совсем; я написал решение для неотрицательных целых чисел; но его можно переписать для «токенов» непустых символов, разделенных пробелами.)
Я начинаю со следующего входного файла:
$ cat lipid-inputs
124 150 178 111 143 177 116
154 194 139 183 132 180 133
185 142 101 159 122 184 151
120 188 161 136 113 189 170
Мы хотим сгруппировать 28 входных чисел в наборы по десять чисел в каждом и представить выходные данные с (максимум) семью числами в строке. Итак: будут две полные группы и третья группа только с восемью номерами участников (так как у нас всего 28 входов). Желаемый результат выглядит следующим образом:
[Lipid 1]
124 150 178 111 143 177 116
154 194 139
[Lipid 2]
183 132 180 133 185 142 101
159 122 184
[Lipid 3]
151 120 188 161 136 113 189
170
Стратегия: сначала напишите входные числа по одному в строке, чтобы затем мы могли расположить их по десять в строке (десять: количество элементов желаемых групп в выходных данных). Затем добавьте номера строк (которые будут go в строках меток). Затем отредактируйте строки «номера строки», чтобы добавить «липидный» материал, и разбейте строки данных на более короткие строки, показывая по семь токенов в каждой (возможно, меньше в последней строке в каждой группе).
Реализация: tr
разбивать жетоны по одному на строку; paste
многократное чтение со стандартного ввода, десять строк стандартного ввода для каждой строки вывода; затем sed =
, чтобы добавить номера строк (в отдельных строках); и наконец стандартный sed
для окончательного редактирования. Команда выглядит так:
$ tr -s ' ' '\n' < lipid-inputs | paste -d ' ' - - - - - - - - - - |
> sed = | sed -E 's/^[[:digit:]]+$/[Lipid &]/ ;
> s/(([[:blank:]]*[[:digit:]]+){7}) /\1\n/g'
Результат - тот, который я уже показал.
Для обобщения (чтобы вы могли применить к своей проблеме): количество токенов в строке в входной файл не имеет значения. Чтобы получить 15 токенов на строку в выводе , измените жестко запрограммированное число с 7 на 15 в последней строке команды, показанной выше. И чтобы выделить 129 токенов на строку вместо 10, нужно изменить команду paste
: я показываю, что она десять раз читает из стандартного ввода. Вам нужно 129. Таким образом, было бы лучше создать строку из 129 тире, разделенных пробелом, в простой команде - а не жестко - и использовать эту строку в качестве входных данных для paste
. Я покажу, как это сделать на моем примере, вы адаптируетесь к своему.
Определите переменные для хранения ваших соответствующих значений: сколько токенов на липид (129 в вашем случае, 10 в моем) и сколько токенов на в выводе (15 в вашем случае, 7 в моем).
$ tokens_per_lipid=10
$ tokens_per_line=7
Затем создайте переменную для хранения строки - - - - [...]
, необходимой в команде paste
. Есть несколько способов сделать это, вот только один:
$ paste_arg=$(yes '-' | head -n $tokens_per_lipid | tr '\n' ' ')
Давайте проверим:
$ echo $paste_arg
- - - - - - - - - -
Хорошо, давайте переписываем команду, которая делает то, что вам нужно. Мы должны использовать двойные кавычки для аргумента sed
, чтобы разрешить расширение переменной.
$ tr -s ' ' '\n' < lipid-inputs | paste -d ' ' $paste_arg |
> sed = | sed -E "s/^[[:digit:]]+$/[Lipid &]/ ;
> s/(([[:blank:]]*[[:digit:]]+){$tokens_per_line}) /\1\n/g"
[Lipid 1]
124 150 178 111 143 177 116
154 194 139
[Lipid 2]
183 132 180 133 185 142 101
159 122 184
[Lipid 3]
151 120 188 161 136 113 189
170