Вопрос: Создание алфавитного индекса из электронной таблицы


У меня есть текстовый файл с лекционными темами из моего класса физики, который выглядит так:

1/14,Galilean relativity,Einsteinian relativity,Minkowski space,Henri Poincare,,
1/16,Lorentz transformations,Velocity transformations,Proper time,Light aberration,Lorentz tensors formalism,Minkowski space
1/23,Lorentz boost,Lorentz group,Poincare group,contravariant tensor,covariant tensor,d'Alembertian

Я фактически храню его как Google Doc, поэтому я могу экспортировать его в виде tsv, ods, xslx и т. Д. Вместо csv.

Я хочу создать индекс, как вы бы видели в конце книги, перечисляя темы по алфавиту по дате, например.

d'Albertian 1/23
... (more entries)
Minkowski space 1/14 1/16
... (more entries)
Velocity transformations 1/16

или если вы хотите получить фантазию:

d'Albertian ................. 1/23
... (more entries)
Minkowski space ............. 1/14, 1/16
... (more entries)
Velocity transformations .... 1/16

Я сначала подумал об использовании LaTeX, но пакеты индексирования, похоже, идут по номеру страницы, а не произвольная строка, такая как дата. Фактически, «MakeIndex предполагает, что все номера страниц являются арабскими или строчными римскими цифрами»; http://www.tex.ac.uk/ctan/indexing/makeindex/doc/makeindex.pdf, Кроме того, входной файл для makeindex должен быть список с одной темой и номером страницы на строку; он просто сортирует и форматирует: http://www.troubleshooters.com/linux/lyx/makeindex.htm

Итак, программное обеспечение, которое я ищу, должно сделать это:

  1. Примите формат csv, tsv или другой формат электронной таблицы. Это было бы идеально, но я был бы в порядке с текстовым форматом, который можно было бы легко сгенерировать из файла электронной таблицы, например. заменой awk или sed,
  2. Свяжите первую запись каждой строки (например, дату 1/14) с каждой из следующих записей (например, темы Galilean relavity, Minkowski space, и т.д.).
  3. Сортировка всех тем для всех дат в алфавитном порядке.
  4. Объедините темы, которые появляются более одного раза в одной записи, перечисляя каждую дату, в которой появляется тема.
  5. Выведите результат как стандартный формат.

Моим единственным требованием к программному обеспечению является то, что он работает в Linux.

Я не суетливый в отношении формата вывода; текстовый файл, LaTeX, HTML, odf и т. д. все в порядке, пока я могу распечатать бумажную копию.


2
2018-04-25 17:26


Источник




Ответы:


Вы против моно? Если нет, то получите F # interactive

http://fsharp.org/use/linux/

и используйте следующий скрипт F # (вы также можете его скомпилировать)

open System
open System.IO

let inputFile = "inputFile.csv"
let outputFile = "out.txt"

File.ReadAllLines(inputFile)
|> Seq.filter (fun i -> i.Length > 0)
|> Seq.collect
    (fun i ->
        let fields = i.Split(',')
        let date = fields.[0]
        fields.[1..] |> Array.map (fun entry -> date,entry)
    )
|> Seq.groupBy snd
|> Seq.sortBy (fun (entry,_) -> entry.ToUpper())
|> Seq.filter (fun (entry,_) -> entry <> "")
|> Seq.map 
    (fun (entry,dates) ->
        let dates = dates |> Seq.map fst |> Seq.sort
        let datestr = String.Join (", ",dates)
        String.Format("{0} ........ {1}", entry, datestr)
    )
|> (fun i -> File.WriteAllLines(outputFile,i))

Это приведет к созданию текстового файла:

contravariant tensor ........ 1/23
covariant tensor ........ 1/23
d'Alembertian ........ 1/23
Einsteinian relativity ........ 1/14
Galilean relativity ........ 1/14
Henri Poincare ........ 1/14
Light aberration ........ 1/16
Lorentz boost ........ 1/23
Lorentz group ........ 1/23
Lorentz tensors formalism ........ 1/16
Lorentz transformations ........ 1/16
Minkowski space ........ 1/14, 1/16
Poincare group ........ 1/23
Proper time ........ 1/16
Velocity transformations ........ 1/16

Не совсем то, что вы хотите, но было бы легко изменить приведенное выше, чтобы произвести латексную разметку. Просто измените строку

String.Format("{0} ........ {1}", entry, datestr)

для включения нужной отметки для каждой строки. К сожалению, у меня нет доступа к моно прямо сейчас, поэтому он протестирован с .NET.


2
2018-04-25 17:59



У меня возникла проблема с компиляцией из источника, поэтому я установил пакет здесь: [fsxplat.codeplex.com/releases/view/55463], В нем говорится: error FS0222: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule' - Nathaniel M. Beaver
попробуйте добавить «модульную программу» в начало файла (без кавычек) - jizugu
generate-index.fs(22,41): error FS0001: This expression was expected to have type string [] but here has type seq<string> - Nathaniel M. Beaver
Вот строка 22: let datestr = String.Join (", ",dates), dates находится в позиции (22, 41) - Nathaniel M. Beaver
try: let datestr = String.Join (",", date |> Seq.toArray) - jizugu


Сценарии Shell и славные awk команда:

awk -F, '
  { for (i=2;i<=NF;i++) { subject_dates[$i]=subject_dates[$i] " " $1 } }
  END { for (idx in subject_dates) { print idx, subject_dates[idx] } }
'

2
2018-04-25 19:37



Пришлось удалить две запятые в конце строки ввода 1, чтобы избежать нулевой строки на выходе. - Ramillete
Можно awk сортировать выход? Прямо сейчас я должен пропустить его через сортировку, чтобы получить его в алфавитном порядке. Кроме того, насколько сложно было бы устранить двойные пробелы после темы? (Кроме того, первая строка возвращает все даты, поэтому я фильтрую ее с помощью tail -n +2.) - Nathaniel M. Beaver


И F# а также awk решения работают хорошо с несколькими настройками. Тем не менее, я решил пойти со следующим скриптом python:

#!/usr/bin/env python
import csv, sys
mydict = {}
for line in open(sys.argv[1],'r'):
    tokens = line.strip().split(',')
    item, keys = tokens[0], tokens[1:]
    for key in keys:
        if key != '':
            # If the key is already in the dictionary,
            # just add it to the set, otherwise make an
            # empty set to add the item to.
            mydict.setdefault(key, set()).add(item)
for key in sorted(mydict.keys(), key=str.lower):
    print key + ' \dotfill ' + ', '.join(mydict[key])

В этом случае, item соответствует дате и keys соответствуют темам. \dotfill это разметка LaTeX для заполнения горизонтальных пространств точками.


2
2018-04-26 06:07