Как использовать сортировку V по горизонтали? - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть эта таблица:

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  Picnick#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 

Кто-нибудь знает, как сортировать по горизонтали на основе значения, когда у нас также есть текст?

Я пытался использовать сортировку -V в комбинациях переменных \ с комбинацией с сортировкой kn. Также я пытался изменить этот код

awk ' {split( $0, a, " " ); asort( a ); 
for( i = 1; i <= length(a); i++ ) printf( "%s ", a[i] ); 
printf( "\n" ); }'

, который сортирует таблицы только тогда, когда у нас есть цифра c таблица значений по горизонтали.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Вы можете использовать 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 с массивом ввода и вывода и определяемой пользователем функцией сравнения.

1 голос
/ 14 февраля 2020

Я использовал функцию asorti для сортировки массива, где индексами являются числа, извлеченные из элементов. Я заполнил элементы начальными нулями, потому что asorti сортирует лексически, а не численно. После сортировки я просто печатаю элементы.

awk '{
    split($0, a, " ");

    for (i in a) {
        # extract number
        v = a[i]
        gsub(/.*#/, "", v)
        # because asorti sorts alphabetically, I fill indexes with zeros
        b[sprintf("%020d", v)] = a[i]
    }

    # sort using indexes
    n = asorti(b, dest)

    # output
    for (i = 1; i <= n; i++) {
        printf "%s%s", b[dest[i]], i == n ? "\n" : " "
    }

    # if we dont delete b, it will only grow. So delete it.
    delete b
}' <<'EOF'
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
EOF

вывод:

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

Я тестировал на tutorialspoint . Вы можете направить вывод в column -t -s ' ' -o ' ', чтобы получить вывод в столбце, или сделать это в awk, как с printf "%-9s%s".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...