我想用 Markdown 来写我的毕业论文。可悲的是,没有完美的编辑器,所以我必须即兴创作。对于 bibtex 引文,我想在处理 pandoc 的输入之前用某种 bash-filter 转换我自己的定义:
<@BIBTEX_ID[|OPTIONAL_PAGE_OR_CHAPTER_NUM[|OPTIONAL_UNIT_DEFINITION]]>
像这样的东西:
\autocite[OPTIONAL_UNIT_DEFINITION][OPTIONAL_PAGE_OR_CHAPTER_NUM]{BIBTEX_ID}
例子:
<@sample> ---> \autocite{sample}
<@sample|12> ---> \autocite[12]{sample}
<@sample|12|c.> ---> \autocite[12][c.]{sample}
哪个 bash/unix 工具可以完成这项工作?可以用 sed 或 awk 来完成吗?
答案1
您可以sed
直接使用它:
sed -e 's/<@\([^|>]*\)|\([^|>]*\)|\([^>|]*\)>/\\autocite[\2][\3]{\1}/g' \
-e 's/<@\([^|>]*\)|\([^|>]*\)>/\\autocite[\2]{\1}/g' \
-e 's/<@\([^|>]*\)>/\\autocite{\1}/g'
这只是分别替换每个可能的公式:第一个处理三参数引用,然后是两个,然后是一个。每个可选块都与 匹配\([^|>]*\)
,并用 替换到输出中\1...3
。
答案2
sed '/^<@\([^|]*\)\(.*\)>/!b
s//\\autocite\2{\1}/
s/|/[/;s/|/][/g;/\[/s/{/]{/
' <<\DATA
<@sample>
<@sample|12>
<@sample|12|c.>
DATA
输出
\autocite{sample}
\autocite[12]{sample}
\autocite[12][c.]{sample}
要做的第一件事sed
是验证它正在处理的行以 开头,<@
后跟某个>
.如果该行与该模式不匹配,它将b
跳出脚本以开始下一行循环并重试。
但是,如果它确实匹配,则会通过引用后面不是该字符的所有或任何字符以及引用第一个序列后面的所有或任何字符直到该行最后一次出现来sed
完成一点双重任务。在下一行(仅当第一行匹配时才能到达)从第一个地址借用这些引用并将整个字符串替换为。\1
@
|
\2
>
sed
\\autocite\2{\1}
在下一行中,sed
尝试将第一次出现的字符替换|
为 a [
,然后将更多|
字符替换为][
, 最后,如果[
该行中存在 a ,则将第一次出现的字符替换{
为]{
。
所做的一切sed
都很简单。所做的一切sed
都是它刚刚所做的事情的直接结果。sed
秩序井然,有时令人恼火。
顺便说一句 - 这应该处理|
您在一行上指定的尽可能多的单独参数 - 它不限于两个。不过,必须尊重[<>@|{}]
标记和行的位置 - 至少按照书面规定。只要你遵守规则,sed
肯定不会违反任何规则。