Как сортировать этот вывод 1,10,11..2

[обновлено]

возможно, не самый чистый метод, но он работает.

объявить переменную массива и пройтись по ней, используя awkдля подсчета количества типов, совпадающих в объявленном массиве:

declare -a a=("LOCAL" "REMOTE" "BOTH")
types=$(echo ${a[@]} | wc -w)
val=$(echo ${a[@]} | awk -v TYPE="$TYPE" '{split($0,a," ");for (key in a) {if (a[key] != TYPE) print "#"}}' | wc -l)
if [ $val -eq $types ]; then # if 0 matches 
   echo "error"; exit 1; 
fi

спасибо Stéphane Chazelas за указание на ошибку в моем предыдущем ответе.

15
30.08.2020, 02:33
2 ответа

Лучшим вариантом будет подключение к GNU sortс включенной опцией GNU sort's --version-sort

так что это будетoracleasm listdisks | sort --version-sort

Со страницы информации

--version-sort’
     Sort by version name and number.  It behaves like a standard sort,
     except that each sequence of decimal digits is treated numerically
     as an index/version number.  (*Note Details about version sort::.)

На ваш ввод это дает мне

DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
DATA10
DATA11
DATA12
FRA1
FRA2
FRA3
FRA10
FRA11
OCR1
OCR2
OCR3
31
18.03.2021, 23:10

Если sort --version-sortнедоступно, разделите его на 2 поля. :поле 1 = начальные не -цифры, а поле 2 = целое число, и напечатайте поля с помощью TAB между ними. Затем используйте sortна 2 полях с разделителями TAB -, затем удалите TAB. Подключайтесь с помощью каналов, чтобы избежать накладных расходов на ввод-вывод. Вот пример с минимальным срезом данных из ОП плюс несколько дополнительных записей:

echo 1 10 2 11 DATA DATA1 DATA10 DATA11 DATA2 FRA FRA1 FRA10 FRA11 FRA2 | \
    xargs -n1 | \
    perl -lne 'print join "\t", /(\D*)(\d*)/' | \
    sort -k1,1 -k2,2n | \
    perl -pe 's/\t//'

Печать:

1
10
11
2
DATA
DATA1
DATA2
DATA10
DATA11
FRA
FRA1
FRA2
FRA10
FRA11

ДЕТАЛИ:

Вкладки perl one -используют эти флаги командной строки:
-e:указывает Perl искать код в строке -, а не в файле.
-n:перебирает ввод по одной строке за раз, назначая его на $_по умолчанию.
-l:удалить разделитель входных строк("\n"на *NIX по умолчанию )перед выполнением кода в строке -и добавить его при печати.
-p:то же, что и -n, но также printстрока в конце каждого цикла (устраняет явноеprint).

В первой строке -\d— любая цифра (0 -9 ), а \D— любая цифра, отличная от -. Каждый из этих шаблонов повторяется 0 или более раз (с использованием*). Два шаблона фиксируются с помощью круглых скобок и возвращаются как LISTиз двух полей, которые соединяются на вкладке TAB и печатаются.

Второй лайнер Perl one -просто удаляет первую TAB, ничего не находит (пустую строку )и печатает строку.

Для sortна 2 поля используются эти опции :-k1,1:сортировать по полю 1 ASCIIбетатически. Тогда:
-k2,2n:если поле 1 такое же, сортировать по полю 2 численно(-nопция ).
Обратите внимание, что номер поля повторяется дважды (, например, 1,1), чтобы предотвратить сортировку в остальной части строки и ограничить сортировку только этим номером столбца.

11
18.03.2021, 23:10

Теги

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