Сортировка недополненных строк

Дан список неотсортированных строк, не дополненных нулями:

seq 100 | shuf

передача этого в sort даст:

1
10
100
11
12
13
...

потому что sort по умолчанию сортирует лексикографически. Таким образом, у него есть опция числовой сортировки -n, которая даст ожидаемый результат. Однако, если строки не являются полностью числовыми, это не сработает:

seq 100 | shuf | sed s/^/E/ | sort -n

Или для более сложного случая:

paste -dS <(seq 100 | shuf | sed 's/^/E/' | sort -n) <(seq 100 | shuf)
---
E1S70
E10S75
E100S41
E11S53
...

с ожидаемым результатом лексикографической сортировки символов и числовой сортировки чисел:

E1S70
E10S75
E11S53
E100S41

Думайте о числах как об одном блоке, сравниваемом численно с другими числами, но лексикографически с другими символами.

Каков эффективный способ сортировки смешанных строк, не дополненных нулями?

неясно (для меня), каким будет ожидаемый результат для 4-строчного набора данных E*; также неясно, как вы собираетесь сортировать E10S33 / ES204F3 / B27Y23S1 / YF29399G3G3G (и является ли это действительным набором данных); пожалуйста, обновите вопрос, добавив 3-4 разных отсортированных набора данных (по 4-5 строк каждый)

markp-fuso 08.08.2024 01:42

без дополнительных примеров и четких объяснений я догадаюсь, что sort -V (или sort --version-sort) может быть тем, что вы хотите

markp-fuso 08.08.2024 01:45

Это было бы расширение GNU, да? sort -v или --version-sort

Jetchisel 08.08.2024 02:12

Обновлено. Другой способ увидеть это состоит в том, что все числа дополняются, затем сортируются лексикографически, а затем не дополняются. Это ожидаемый результат. Вот почему я задал второй вопрос о том, есть ли способ дополнить/распечатать строки, смешанные с числами.

AvidSeeker 08.08.2024 03:12

Да, что-то вроде sort -V — это то, что я ищу, но, к сожалению, в сложном случае это не работает. Почему?

AvidSeeker 08.08.2024 03:14

Если сомневаетесь, воспользуйтесь преобразованием Шварца. В этом случае украсьте цифры, а затем буквы с четким разделителем столбцов, отсортируйте, а затем уберите декор.

dawg 08.08.2024 03:15

как sort -V неправильно распорядился в вашем «сложном деле»? Я получаю список из 100 строк, отсортированных от E1... до E100..., который выглядит именно так, как вы указали в качестве желаемого результата.

jhnc 08.08.2024 05:39

Виноват. sort -V кажется, это решение, которое я ищу. Есть какие-нибудь мысли по моему второму вопросу? Я думаю, что ответ @dawg можно изменить, чтобы обнулить числа. Я переместил это в отдельный пост, чтобы сосредоточить внимание на этом: stackoverflow.com/questions/78846515

AvidSeeker 08.08.2024 06:20
В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
1
8
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Данный:

$ cat file
E1S70
E10S75
E100S41
E11S53

Вы можете сделать что-то в этом направлении:

awk '{
        s=t=$0
        gsub(/[^0-9]+/,"\t", s)
        gsub(/[0-9]+/,"\t",t)   
        $0=sprintf("%s\t%s\t%s",s,t,$0)
    }1' file | sort -n | awk '{print $NF}'

Распечатки:

E1S70
E10S75
E11S53
E100S41

При этом используется идиома Украсить, Сортировать, Убрать для добавления столбцов для разделения элементов, которые вы хотите использовать для сортировки; в данном случае цифры, а затем буквы.

этот код, кажется, неправильно упорядочивает образец ввода в моем ответе (B27... должен предшествовать E...) и (возможно) ES020.4F3 должен идти после ES20.14F3)

jhnc 08.08.2024 05:54

может быть: awk '{s=$0; gsub(/[0-9]+/," & ",s); print s,$0}' file|... ? Все еще есть ошибки, если строки не всегда состоят из одинакового количества частей.

jhnc 08.08.2024 07:35
Ответ принят как подходящий

Кажется, вы описываете натуральный сорт:

естественный порядок сортировки (или естественная сортировка) — это упорядочение строк в алфавитном порядке, за исключением того, что многозначные числа обрабатываются атомарно, т. е. как если бы они были одним символом.

Непонятно, как вы хотите обрабатывать дробные числа (могут быть разделены различными символами, такими как . или ,); или смесь чисел с дополнением нулями и без него.


Для программирования оболочки GNU расширил sort опцией -V/--version-sort, хотя это может не дать того, что вы хотите, для таких списков, как:

B27Y23S1
E10S33
ES020.4F3
ES20.14F3
ES2014F3
YF29399G3G3G

В Perl есть Sort::Versions , Sort::Key::Natural и т. д.

(см. Perl сортирует числа естественно)

В Python есть нацорт и т. д.

(см. Есть ли встроенная функция для естественной сортировки строк?)

В Javascript есть естественная сортировка и т. д.

(см. Естественный вид буквенно-цифровых строк в JavaScript)

Я ожидаю, что другие среды также найдут свои собственные решения.

Другие вопросы по теме