справка по сортировке файла с помощью sort

#bash #sorting

#bash #сортировка

Вопрос:

У меня есть этот файл:

 100: pattern1
                    
1:pattern2
9:pattern2
                   
79: pattern1
61: pattern1
                   
  

и я хочу отсортировать его следующим образом:

                     
1:pattern2
9:pattern2
                   
61:pattern1
79:pattern1
100:pattern1
                   
  

Возможно ли это только с помощью команды сортировки Linux?

Если бы у меня был :

 4:pat1 
3:pat2
2:pat2
1:pat1
  

O / p должен быть:

 1:pat1
             
2:pat2
3:pat2
            
4:pat1
  

Итак, требуется выполнить сортировку по первой группе, но «группировать» по шаблону второй группы.
Пожалуйста, обратите внимание, что после: является шаблоном регулярного выражения, а не литералом.

Комментарии:

1. Каковы критерии для первой и второй группы?

2. Я понимаю, что вы пытаетесь сгруппировать строки в зависимости от того, что идет после ‘:’, и выводите разделительную строку между группами, но я не понимаю, как вы хотите, чтобы группы были отсортированы. Вы предполагаете, что диапазон числовых значений перед ‘:’ никогда не будет перекрываться между группами? То есть, если у вас есть «1: a», «2: b», «3: b» и «4: a», вы хотите получить «a» первыми или «b» первыми?

3. почему первая сотня попадает во вторую группу? Каковы критерии сортировки? По тексту, следующему за номером? значит, «1000: wow» войдет в 1-ю группу, а «1: это оно» — во вторую?

4. Похоже, вам было бы лучше вставить s самостоятельно после просмотра каждой строки после сортировки, и вы видите, что значение после : изменилось.

Ответ №1:

Лучшее, что вы можете сделать, это отсортировать его в соответствии с числовыми значениями. Но вы ничего не можете сделать со строкой » «-.

 $ sort -n input
                   
                   
                    
1:wow
9:wow
61: this is it
79: this is it
100: this is it
  

Ответ №2:

Я не верю, что sort один может сделать то, что вам нужно.

Создайте новый сценарий командной строки и поместите это в его содержимое (ie mysort.sh ):

 #!/bin/sh
IFS=$'n' # This makes the for loop below split on newline instead of whitespace.
delim=                   
for l in `grep -v ^ | sort -g`      # Ignore all   lines and sort by number
do
    current=`echo $l | sed s/^[0-9]*://g` # Get what comes after the number
    if [ ! -z "$prev" ] amp;amp; [ "$prev" != "$current" ] # If it has changed...
    then                                  #  then output a      delimiter line.
        echo $delim
    fi
    prev=$current
    echo $l                               # Output this line.
done
  

Чтобы использовать его, передайте содержимое вашего файла следующим образом:

 cat input | sh mysort.sh
  

Ответ №3:

Вероятно, нет — это не тот формат, который ожидает sort (1). И если бы вы это сделали, это был бы один из тех удивительных хаков, которые нелегко использовать. Если у вас есть какое-то правило для того, что находится между строками со знаками плюс, вы можете достаточно легко выполнить это с помощью скрипта AWK, Perl или Python.

Ответ №4:

Если ваш ввод был разделен пробелом, а не ‘:’:

 sort  -rk2 | uniq -D -f1
  

будет выполнять группировку;

  • Я предполагаю, что вам нужно будет отсортировать «подразделы» позже (к сожалению, my sort(1) не выполняет упорядочение составных ключей. Я верю, что есть версии, которые позволяют вам делать sort -k2,1n , и вы бы закончили сразу).
  • используйте --all-repeated=separate вместо -D , чтобы получить пустые разделители между группами. Посмотрите на man uniq , чтобы узнать больше идей!

Однако, поскольку ваш ввод разделен двоеточием, требуется взлом:

 sed 's/([0123456789] ):/1 /' t | sort  -rk2 | uniq -D -f1
  

HTH