Вы можете использовать asort
со своей собственной функцией сравнения
awk 'function trailing_number_compare(i1, v1, i2, v2, _a, _l, _r, _n)
{
_n = split(v1, _a, "#");
_l = 0 + _a[2];
_n = split(v2, _a, "#");
_r = 0 + _a[2];
if (_l < _r)
return -1
else if (_l == _r)
return 0
else
return 1
}
{
split($0, a, FS);
n = asort(a, b, "trailing_number_compare");
for(i = 1; i <= n; i++)
{
printf("%s ", b[i]);
}
printf("\n");
}' "$@"
Ввод вопроса
flame#43 king#402 Picnic#51 Sar#360 far#66
flame#61 king#63 Picknic#67 Sar#66 far#65
flame#63 king#60 Packnic#69 Sar#64 far#58
приводит к получению
flame#43 Picnic#51 far#66 Sar#360 king#402
flame#61 king#63 far#65 Sar#66 Picknic#67
far#58 king#60 flame#63 Sar#64 Packnic#69
Функция trailing_number_compare
основана на примере в https://www.gnu.org/software/gawk/manual/html_node/Array-Sorting-Functions.html
Аргументы функции, начинающиеся с _
, используются в качестве локальных переменных.
Объяснение:
function trailing_number_compare(i1, v1, i2, v2, _a, _l, _r, _n) { ...}
Определите функцию, которая будет передана в asort
для пользовательского сравнения двух элементов. Он получит аргументы индекса 1 i1
, значения 1 v1
, индекса 2 i2
и значения 2 v2
. Другие аргументы не будут установлены вызывающей стороной и используются в качестве локальных переменных в функции.
_n = split(v1, _a, "#");
разбить v1
на массив _a
в разделителе "#"
, _n
будет числом полей и может использоваться для проверки или перебора массива.
_l = 0 + _a[2];
назначить 2-е поле _l
. Добавление 0 сил цифр c context.
Аналогично для v2
и _r
...
Наконец, сделайте сравнение _l
и _r
, возвращаемое значение используется asort
Действие, которое будет выполняться со всеми входными строками, очень похоже на исходный код, за исключением того, что я использую FS
(разделитель полей) для разделения ввода и вызова asort
с массивом ввода и вывода и определяемой пользователем функцией сравнения.