Гольф сценарий, который извлекает цитаты из документа LaTeX - PullRequest
0 голосов
/ 02 октября 2019

Я пытался извлечь все цитаты из файла LaTeX, то есть иметь возможность извлечь все, что находится между двумя фигурными скобками после \ cite (то есть, \cite{bla,blo} даст мне bla и blo),Есть несколько угловых случаев: \cite{} может содержать одну или несколько цитат, разделенных запятой (и нет запятой, если есть только одна цитата), а команда \cite{} может занимать несколько строк.

До сих пор я придумал следующий вкладыш, который хорошо работает:

<file.tex grep -oPz "(?s)(?<=\\\\cite{).[^}]*?(?=})" | tr '\n\0,' ' \n\n' | tr -d '[:blank:]' | sort | uniq

Однако мне было интересно, можно ли будет сделать это только одним инструментом, будь то sed, grep или awk. Я думаю, что было бы легче сделать это в awk (потому что часть sort | uniq может быть легко выполнена в awk, но я застрял в извлекающей части).

Любые предложения приветствуются.

Вот контрольный пример:

Aenean consequat \cite{acitation} auctor varius. Pellentesque varius,
 sapien quis faucibus rhoncus, nunc nisl sagittis erat, ac varius magna
 quam eu est. Pellentesque \cite{a citation with spaces is considered
 valid yes but does not produce the correct output but it is not a problem
 because those are not valid in LaTeX} congue maximus efficitur. Quisque
 ac aliquam nisi. Nullam sit
 amet auctor metus, nec varius ipsum. Proin vel lacus sed nisl auctor
 porttitor. Sed id turpis pretium, rhoncus nisi eu, dictum ipsum. Nulla
 facilisi. Vestibulum sed congue \cite{some.citation.here, anotherone} 
metus, vitae \cite{onecitation,
thenexthere} scelerisque sem.Vestibulum eget gravida ante. Suspendisse 
consequat libero eget mauris cursus, sed blandit est euismod. Pellentesque
 porta vitae dolor blandit lacinia. Nulla sit amet rutrum velit, in mollis
 sem. Nunc gravida consectetur \cite{acitation} feugiat.

и вывод

acitation
acitationwithspacesisconsideredvalidyesbutdoesnotproducethecorrectoutputbutitisnotaproblembecausethosearenotvalidinLaTeX
anotherone
onecitation
some.citation.here
thenexthere

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

\cite{a citation with spaces is considered
 valid yes but does not produce the correct output but it is not a problem
 because those are not valid in LaTeX}

- неопределенное поведение, так как он не должен появляться в действительном документе LaTeX.

Ответы [ 2 ]

2 голосов
/ 02 октября 2019

Не могли бы вы попробовать следующее (поскольку я на мобильном телефоне не смог проверить его, должен работать, но).

awk -v RS="" '{while(match($0,/\\cite{[^}]*/)){val=substr($0,RSTART+6,RLENGTH-6);array[val]++;$0=substr($0,RSTART+RLENGTH)}} END{for(i in array){if(array[i]==1){gsub(/,/,ORS,i);print i}}}' Input_File

Редактировать:

BEGIN {
  RS=""
}

{
  gsub(/ *, */, ",", $0);
  gsub(/ |\n/, "", $0);
  while (match($0,/\\cite{[^}]*/)) {
    val = substr($0, RSTART+6, RLENGTH-6);
    split(val, array, ",");
    for (x in array)
      citations[array[x]]++
    $0 = substr($0, RSTART + RLENGTH)
  }
}

END {
  for(i in citations)
      print i
}
1 голос
/ 03 октября 2019

Это может работать для вас (GNU sed):

sed -n '/\n/bb;/\\cite{/!b;s//\n/;s/.*\n/\n/;:a;/}/!{N;s/\n//2;ba};s//\n/;D;:b;s/^\([^\n]*\),\s*/\1\n/;P;D' file

Этот сценарий sed использует тот факт, что команда D удаляет до и включая первый \n в пространстве шаблона (еслиесть один), а затем представляет остатки пространства шаблона для цикла Sed. Если пространство шаблона пустое, оно ведет себя так же, как и команда d, и извлекает следующую строку (за вычетом новой строки) в пространство шаблона и запускает цикл sed как обычно.

Сценарийиз двух частей: если пространство шаблона содержит новую строку (возможно, только если оно уже обработано и введена новая строка), оно передается в маркер goto :b, в противном случае пространство шаблона обрабатывается следующим образом.

Если пространство шаблона не содержит \\cite{, оно удаляется и цикл sed повторяется. В противном случае пространство шаблона сокращается до начала цитаты и вставляется новая строка. Конец цитаты, отмеченный закрывающей }, также заменяется новой строкой (цикл используется в том случае, если цитата проходит по одной или нескольким строкам), а затем команда D используется для отправки sed веще раз.

По возвращении, удалив первый введенный символ новой строки, цитата теперь находится в начале пространства шаблона. Отдельные цитаты печатаются путем замены , перед вторым введенным символом новой строки новой строкой, и цикл sed повторяется до тех пор, пока не будет достигнуто закрытие цитаты. Затем оставшаяся часть шаблона многократно обрабатывается, пока он не станет пустым или не будет содержать дальнейших ссылок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...