Сортировка списка по номерам

Вероятно, вам потребуется добавить исключение для этого хоста в файл java.security, расположенный в ваших путях JRE/JDK. Если вы используете прокси-сервер или у вас есть какие-либо самоподписанные или не корневые доверенные сертификаты в цепочке (или вы осуществляете доступ через http, а не https ), вам нужно сообщить Java, что это нормально..

0
18.03.2021, 14:49
4 ответа

Это (с использованием GNU awk в качестве третьего аргумента для match(), gensub(), sorted_inиFPAT)будет сортировать только нужный раздел (, т.е. коллекция "one" с порядковым номером "292" или выше ), может обрабатывать заголовки, содержащие любые символы или строки, включая ;, (, )или (volume <N>), и выводит отсортированный раздел в своем исходное место в несортированных окружающих секциях:

$ cat tst.awk
BEGIN {
    RS = ""
    ORS = "\n\n"
    FPAT = "[^;]*(\"[^\"]*\")*[^;]*"
    tgtColl = "one"
    begSeqNr = 292
    maxSeqs = 100
}
match($2,/Collection (.*) \(volume ([0-9]+))/,a) {
    coll  = a[1]
    volNr = a[2]
    seqNr = $1+0
}
(coll == tgtColl) && (seqNr >= begSeqNr) && (++seqCnt <= maxSeqs) {
    vols[volNr] = $0
    next
}
{
    prtVols()
    print
}
END { prtVols() }

function prtVols(       volNr, seqNr, vol) {
    PROCINFO["sorted_in"] = "@ind_num_asc"
    seqNr = begSeqNr
    for (volNr in vols) {
        vol = vols[volNr]
        sub(/[0-9]+/,seqNr++,vol)
        print vol
    }
    delete vols
}

Например, учитывая этот ввод, измененный из случая солнечного -дня в вопросе, чтобы добавить пару полезных тестовых примеров:

$ cat file
  100G.- some earlier collection ; Collection zero (volume 1) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST earlier collection ID

  200G.- right collection, too early sequence number; Collection one (volume 6) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
  - TEST earlier sequence number

  292G.- La Ilíada ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
  - I have to download more ancient greek texts.
  - Another note line.

  293G.- El Quijote ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
  - Masterpiece.

  294G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
  - Russian masterpiece.

  295G.- "Kill Bill; Bury Him (volume 2)" ; Collection one (volume 5) ; Tarantino ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST quoted title with sparator chars and target string

  296G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - I read this one as a kid.

  300G.- some later collection ; Collection twenty-three (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST later collecion ID

будет вывод:

$ awk -f tst.awk file
  100G.- some earlier collection ; Collection zero (volume 1) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST earlier collection ID

  200G.- right collection, too early sequence number; Collection one (volume 6) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
  - TEST earlier sequence number

  292G.- El Quijote ; Collection one (volume 1) ; Miguel de Cervantes ; http://www.daemcopiapo.cl/Biblioteca/Archivos/7_6253.pdf
  - Masterpiece.

  293G.- La isla del tesoro ; Collection one (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - I read this one as a kid.

  294G.- La Ilíada ; Collection one (volume 3) ; Homer ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Homero/Iliada.pdf
  - I have to download more ancient greek texts.
  - Another note line.

  295G.- Crimen y castigo ; Collection one (volume 4) ; Fiódor Dostoyevski ; http://www.ataun.eus/BIBLIOTECAGRATUITA/Cl%C3%A1sicos%20en%20Espa%C3%B1ol/Fedor%20Dostoiewski/Crimen%20y%20castigo.pdf
  - Russian masterpiece.

  296G.- "Kill Bill; Bury Him (volume 2)" ; Collection one (volume 5) ; Tarantino ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST quoted title with sparator chars and target string

  300G.- some later collection ; Collection twenty-three (volume 2) ; Robert Louis Stevenson ; https://www.biblioteca.org.ar/libros/130864.pdf
  - TEST later collecion ID

Поскольку это разделитель полей, любое ;, которое появляется в заголовке, должно быть заключено в двойные кавычки, либо само по себе Kill Bill";" Bury Him, либо как часть всего заголовка в кавычках, как в приведенном выше примере, никаких других символов или строк. в заголовке нужно какое-то особое обращение.

Если вам действительно нужна вся коллекция one, а не только начиная с порядкового номера или наоборот -, это чрезвычайно тривиальная настройка и очевидно, что просто не проверять одно или другое, и аналогично, если вы хотите все коллекция, отсортированная, начиная с заданного begSeqNrвместо 100 из них, просто не включайте текст для seqCnt, и если вы не хотите, чтобы окружающие коллекции/последовательности печатались, просто избавьтесь от отдельного printутверждение.

1
22.03.2021, 13:40

Вы не указали явное требование к языку, поэтому вот грязное решение в python 3.8. Я уверен, что кто-то другой может придумать что-то лучше, но этого должно быть достаточно.

Код предполагает, что текст находится в файле с именем list.txt в текущем каталоге, и будет создан новый файл с именем new -list.txt

Он также не обрабатывает отсутствующий пробел в "-La isla del tesoro"

import re

booklist = []
bookcount = 0
entry = ''
line_numbers = []

# Find and return the volume number for a book
def get_volnum(book):
        volstring = ''
        volstring = re.search('\\(volume (\d+)\\)', book)
        volnum = volstring.group(1)
        return volnum

# Read file and put in doc variable
doc = open('list.txt', 'r').readlines()

# Group each book in a single string and append in a booklist
for line in doc:
    # if line begins with three decimals followed by 'G.', put line in a new entry. 
    if re.match("(\d\d\d)G.*", line): 
        #read the line number and append to a list
        line_numbers.append(line.split('G.')[0])
        # Add previous entry to booklist (without the three decimals and G.)
        if bookcount > 0:
            booklist.append(entry.split('G.')[1])  

        entry = line
        bookcount +=1
    # If line begins with a '- ', concatenate the line into the current entry.
    if line.startswith('- '):
        entry += line

#Append last line
booklist.append(entry.split('G.')[1])  
# Make a list (booktable) that contains [volnum, book]
booktable = []
[booktable.append([get_volnum(book), book]) for book in booklist]

# Sort that list by volnum (index 0 of each list item of booktable)
booktable.sort(key=lambda x: int(x[0]))

line_numbers.sort()

# Write result to file
f = open("new-list.txt", "w")
for b in booktable:
    f.write(line_numbers.pop(0) + 'G.' + b[1])
    f.write('\n')

f.close()
3
21.03.2021, 01:12

Через awkи функцию GNU-(!)определения обхода массива. Примечание :сохраняет весь файл в ОЗУ один раз, но вы сказали «более 100 томов», поэтому я предполагаю, что файл не очень большой.

Идея

  1. отдельные записи пустыми строками (два символа новой строки подряд, TAB не предполагается)
  2. использовать круглые скобки в качестве разделителей полей :получить строки в массив с номером тома в качестве идентификатора индекса. Поэтому число должно быть отделено с помощьюsub
  3. сортировать вывод по индексу "том X"
  4. просто замените числа (293G и т. д. )для каждой записи в отсортированном виде

Скрипт:

BEGIN { RS="" ; ORS="\n\n" ; FS="[()]" }

{id=$2 ; sub(/volume /,"",id) ; vol[id]=$0}    

END {PROCINFO["sorted_in"]="@ind_num_asc"
    n=292
    for ( id in vol ) { gsub(/^\t.../,"\t"n++,vol[id]) ; print vol[id] } }

Выполнить через

awk -f script inputfile
1
21.03.2021, 09:51
<infile awk -F';' -v RS= '
        /Collection one/{ n=$2; gsub(/[^0-9]*/, "", n); sub(/[0-9]+/, 292+n-1) }
        { print sep $0; sep="\0" }' |sort -z |tr '\0' '\n'
0
22.03.2021, 08:35

Теги

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