Я хотел бы очистить и отсортировать возвращаемый результат команды bash.

В настоящее время вывод довольно неорганизован:

00000000-0000-0000-A000-4A414D460003
C145DC85-D209-4062-BC35-E24D27BC399E
com.adobe.lightroom
E38D2355-BD4D-45FE-9F1E-979F2493099A
com.apple.safari
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
com.apple.airplay
com.apple.bonjour
0343C308-CE79-4D3B-90F5-D32122234378


Я хочу перенести строчные элементы в верхнюю часть списка, отсортировать их по алфавиту, а затем переместить более длинные строки UUID в нижнюю часть списка.

com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378
C145DC85-D209-4062-BC35-E24D27BC399E
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
1
Jim Smith 29 Авг 2019 в 03:56

3 ответа

Лучший ответ

Пожалуйста, попробуйте следующее:

while IFS= read -r line; do
    if [[ $line == [a-z]* ]]; then
        printf "%s%c%s\n" "$line" $'\t' "A"
    else
        printf "%s%c%s\n" "$line" $'\t' "B"
    fi
done < list.txt | sort -t $'\t' -k2 -k1 | cut -f1

Результат:

com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378
C145DC85-D209-4062-BC35-E24D27BC399E
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C

Его примитивный подход заключается в добавлении знака «А» или «В» во втором столбце, чтобы отличать строчные буквы от других.

В качестве альтернативы, если perl является вашим вариантом, попробуйте:

perl -e '
print map { $_->[0] }
    sort { $a->[1] <=> $b->[1] or $a->[0] cmp $b->[0] }
    map { [$_, /^[a-z]/ ? 0 : 1] } <>;
' list.txt

Он использует Schwartzian transform в Perl.
Надеюсь это поможет.

1
tshiono 29 Авг 2019 в 07:45

Попробуй это:

sort myfile.txt | tee >(grep -Pv "^[0-9A-F]{8}.+") >(grep -P "^[0-9A-F]{8}.+") > /dev/null

Сначала он сортирует файлы, затем выполняет поиск строк UUID и выводит их последними.

Мое определение UUID - любая строка, начинающаяся с 8 символов: 0-9 или A-F (заглавная).

1
Addison 29 Авг 2019 в 01:47

Обратный "sort -r" сделает это. Это работает, потому что если вы посмотрите на таблицу ascii, то заметите, что строчные буквенные символы находятся в конце.

$ cat output
00000000-0000-0000-A000-4A414D460003
C145DC85-D209-4062-BC35-E24D27BC399E
com.adobe.lightroom
E38D2355-BD4D-45FE-9F1E-979F2493099A
com.apple.safari
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
com.apple.airplay
com.apple.bonjour
0343C308-CE79-4D3B-90F5-D32122234378

$ sort -r output
com.apple.safari
com.apple.bonjour
com.apple.airplay
com.adobe.lightroom
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
E38D2355-BD4D-45FE-9F1E-979F2493099A
C145DC85-D209-4062-BC35-E24D27BC399E
0343C308-CE79-4D3B-90F5-D32122234378
00000000-0000-0000-A000-4A414D460003

Однако это не сортирует строчные буквы в альфа-порядке. Так что переход на лексическую силу perl.

$ cat output | perl -e 'print sort {substr($b,0,1) cmp substr($a,0,1) || $a cmp $b} <>;'
com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
C145DC85-D209-4062-BC35-E24D27BC399E
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378

Сломать команду perl

  • "-e" выполнить следующий скрипт на Perl
  • вывести результаты сортировки, где все внутри {} - это пользовательское сравнение сортировки
  • "substr ($ b, 0,1) cmp substr ($ a, 0,1)" Первая обратная сортировка только по первому символу. Это обратная сортировка, потому что $ b является первым
  • «||» или если они имеют одинаковое значение
  • «$ a comp $ b» Выполняет обычную сортировку в строке для значений, которые имеют одинаковый первый символ.
  • <> читает со стандартного ввода
0
WaltDe 29 Авг 2019 в 18:25