Сортировка по последнему полю строки

$ (function () {$ ("[readonly = 'false']"). removeAttr ("readonly");});
35
задан camh 12 July 2010 в 02:10
поделиться

7 ответов

Вот командная строка Perl (обратите внимание, что ваша оболочка может потребовать от вас экранирования $ s):

perl -e "print sort {(split '/', $a)[-1] <=> (split '/', $b)[-1]} <>"

Просто перетащите в нее список или, если список находится в файле, поместите имя файла в конец командной строки.

Обратите внимание, что этот сценарий на самом деле не изменяет данные, поэтому вам не нужно быть осторожным с тем, какой разделитель вы используете.

Вот пример вывода:

>perl -e "print sort {(split '/', $a)[-1] <=> (split '/', $b)[-1]} " files.txt
/a/e/f/g/h/01-do-this-first
/a/b/c/10-foo
/a/b/c/20-bar
/a/d/30-bob
/a/b/c/50-baz
/a/e/f/g/h/99-local
12
ответ дан 27 November 2019 в 15:41
поделиться

Я думаю, что единственным решением было бы использовать awk :

  1. Поместите последнее поле на передний план, используя awk .
  2. Сортировать строки.
  3. Снова поставьте первое поле в конец.
2
ответ дан 27 November 2019 в 15:41
поделиться

Однострочник в perl для изменения порядка полей в строке:

perl -lne 'print join " ", reverse split / /'

Вы можете использовать его один раз, передать вывод в sort, затем передать его обратно, и вы достигнете того, чего хотите. Вы можете изменить / / / на / +/, чтобы сжать пробелы. И, конечно, вы можете использовать любое регулярное выражение для разделения строк.

3
ответ дан 27 November 2019 в 15:41
поделиться

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

delim=/
new_delim=" "
cat $list \
| sed "s|\(.*\)$delim|\1$new_delim|" \
| sort -t"$new_delim" -k 2,2 \
| sed "s|$new_delim|$delim|"

Проблема заключается в том, чтобы знать, какой разделитель использовать, которого нет в списке. Вы можете сделать несколько проходов по списку, а затем grep для последовательности потенциальных разделителей, но все это довольно неприятно - особенно когда концепция «сортировки по последнему полю строки» выражается так просто, а решение - нет.

Правка: один безопасный разделитель для $ new_delim - NUL, поскольку он не может отображаться в именах файлов, но я не знаю, как поместить символ NUL в сценарий оболочки bourne / POSIX (не bash), а также указать, нужно ли сортировать и sed правильно с этим справится.

1
ответ дан 27 November 2019 в 15:41
поделиться
#!/usr/bin/ruby

f = ARGF.read
lines = f.lines

broken = lines.map {|l| l.split(/:/) }

sorted = broken.sort {|a, b|
    a[-1] <=> b[-1]
}

fixed = sorted.map {|s| s.join(":") }

puts fixed

Если все ответы связаны с perl или awk, то можно решить все на скриптовом языке. (Кстати, сначала я попробовал на Perl и быстро вспомнил, что мне не нравятся списки списков Perl. Хотелось бы увидеть версию от гуру Perl.)

.
0
ответ дан 27 November 2019 в 15:41
поделиться

sort позволяет вам указать разделитель с параметром -t , если я хорошо его помню. Чтобы вычислить последнее поле, вы можете сделать что-то вроде подсчета количества разделителей в строке и суммирования одного. Например, что-то вроде этого (с использованием разделителя ":"):

d=`head -1 FILE | tr -cd :  | wc -c`
d=`expr $d + 1`

( $ d теперь содержит индекс последнего поля).

-1
ответ дан 27 November 2019 в 15:41
поделиться

что-то вроде этого

awk '{print $NF"|"$0}' file | sort -t"|" -k1 | awk -F"|" '{print $NF }'
7
ответ дан 27 November 2019 в 15:41
поделиться
Другие вопросы по тегам:

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