在Bash脚本中使用sed替换LaTeX别名

4

我相对于 bash 脚本编程比较新手,没有 LaTeX 的经验。我被要求开发一个脚本,用来将 LaTeX 文档中的快捷方式替换为它们更繁琐的长式等效语句。

到目前为止,我的方法是将快捷方式和长式分别隔离在不同的变量中,然后尝试使用 sed 在文本中替换它们。我在下面附上了简短的示例文件。

当前脚本需要 2 个参数:一个是 expr 文件,从中获取快捷方式和长式术语,另一个是输入文件,需要进行适当更改。我知道脚本正在正确地隔离快捷方式和长式,并且可以返回它们,但似乎无法执行 sed 命令。

我尝试在互联网上搜索相关信息,并找到了多个类似的问题,建议使用引号组合以解决 sed 变量识别困难的问题。我尝试了许多排列组合,但都不起作用。在许多情况下,长式术语包含特殊字符,例如 '$' 和 '{}',因此我认为这可能是问题所在,但我不确定。我也非常愿意听取其他解决问题的想法。请在下面找到脚本和 2 个参数文件 expr 和 infile 的示例。

expr 文件包含快捷方式和长式术语

% a
\newcommand{\ao}{$^{18}$O}
\newcommand{\aodso}{$^{18}$O/$^{16}$O}
% b
\newcommand{\bea}{\begin{equation}}
\newcommand{\beaa}{\begin{eqnarray}}
% c
\newcommand{\cthree}{C$_3$}
\newcommand{\cfour}{C$_4$}
\newcommand{\coz}{CO$_2$}

包含需要替换为长格式的快捷方式的输入文件

This is my test {\ao} 
{\aodso} my test is this
Does it work {\bea}
{\beaa} test test test
work work work {\cthree}
{\cfour} This is my test
my test is this {\coz}

使用expr和infile作为参数调用的脚本相关子部分

while read line; do
    if [[ $line == \newcommand* ]]; then
    temp=${line#*\{}
    sc=${temp%%\}*} 
    templf=${temp#*\{}
    lf=${templf%\}}
    #echo $sc, $lf
    sed -i -e 's/${sc}/${lf}/g' ${infile}
    fi
done < ${expr}

更新: 为了澄清,期望的结果是将infile中出现的快捷方式替换为相应的长格式。
This is my test {$^{18}$O}
{$^{18}$O/$^{16}$O} my test is this
Does it work {\begin{equation}}
{\begin{eqnarray}} test test test
work work work {C$_3$}
{C$_4$} This is my test
my test is this {CO$_2$}

1
你提供了两个输入文件,很好。现在添加所需的输出。这样更容易理解你需要什么。 - clt60
期望的输出是将infile中所有快捷方式替换为长格式,使其看起来像这样 code这是我的测试{$^{18}$O} code{$^{18}$O/$^{16}$O}我的测试就是这个 code它是否有效{\begin{equation}} code{\begin{eqnarray}}测试测试测试 code工作工作工作{C$_3$} code{C$_4$}这是我的测试 code我的测试就是这个{CO$_2$} - user2460253
3个回答

5

GNU 的代码:

sed -r '/^%/d;s#.*\b(\{\\\w+\})(\{.*\})#\1 \2#;s#\\#\\\\#g;s#(\S+)\s(\S+)#\\|\1|s|\1|\2|g#' file1|sed -f - file2


$ cat file1
% a
\newcommand{\ao}{$^{18}$O}
\newcommand{\aodso}{$^{18}$O/$^{16}$O}
% b
\newcommand{\bea}{\begin{equation}}
\newcommand{\beaa}{\begin{eqnarray}}
% c
\newcommand{\cthree}{C$_3$}
\newcommand{\cfour}{C$_4$}
\newcommand{\coz}{CO$_2$}

$ cat file2
This is my test {\ao}
{\aodso} my test is this
Does it work {\bea}
{\beaa} test test test
work work work {\cthree}
{\cfour} This is my test
my test is this {\coz}

$ sed -r "/^%/d;s#.*\b(\{\\\w+\})(\{.*\})#\1 \2#;s#\\#\\\\#g;s#(\S+)\s(\S+)#\\|\1|s|\1|\2|g#" file1|sed -f - file2
这是我的测试 {$^{18}$O}
{$^{18}$O/$^{16}$O} 我的测试是这个
它是否工作 {\begin{equation}}
{\begin{eqnarray}} 测试测试测试
工作工作工作 {C$_3$}
{C$_4$} 这是我的测试
我的测试是这个 {CO$_2$}

解释:

有两个对于 sed 的调用,第一个从带有搜索/替换模式的文件中创建了一个 sed 脚本:

sed -r '/^%/d;s#.*\b(\{\\\w+\})(\{.*\})#\1 \2#;s#\\#\\\\#g;s#(\S+)\s(\S+)#\\|\1|s|\1|\2|g#' file1
\|{\\ao}|s|{\\ao}|{$^{18}$O}|g
\|{\\aodso}|s|{\\aodso}|{$^{18}$O/$^{16}$O}|g
\|{\\bea}|s|{\\bea}|{\\begin{equation}}|g
\|{\\beaa}|s|{\\beaa}|{\\begin{eqnarray}}|g
\|{\\cthree}|s|{\\cthree}|{C$_3$}|g
\|{\\cfour}|s|{\\cfour}|{C$_4$}|g
\|{\\coz}|s|{\\coz}|{CO$_2$}|g
在第二次调用中,sed 使用文本文件处理此脚本以进行替换。
sed -f - file2

我想知道你是否可以解释一下sed命令是如何工作的?我已经看过了,但还是无法完全理解。在这种情况下,#是什么意思?它与-r标志有关吗?我知道/^%/d;表示如果该行以%开头,则跳过它 但我无法理解其余部分,你能提供任何澄清吗? - user2460253
@user2460253 请查看我的回答。我使用 # 作为 / 的替代,以便使用 sed 命令本身构建一个 sed 脚本。如果它对您有用,请接受我的答案:接受答案:它是如何工作的? --谢谢 :) - captcha

1

在tex.SE的这个问题上有很多关于这个问题的讨论。但我想借此机会指出那里最好的答案(依我之见)是使用de-macro程序,它是一个随TeXLive一起提供的Python脚本。它非常强大,可以处理参数以及简单的替换。

要使用它,您需要将要扩展的宏移动到<something>-private.sty文件中,并使用\usepackage{<something>-private}将其包含到您的文档中,然后运行de-macro <mydocument>。它会输出<mydocument>-private.tex,这与您的原始文档相同,但其中的私有宏已被替换为更基本的内容。


0

我知道这个问题已经被标记为回答了一段时间,而且你明确提到bash和sed是你想要的工具。

然而,为了其他人的利益,如果你不坚持使用bash和sed,还有其他解决方案可供选择,例如perl脚本TME(如SO上建议的那样)。用法:

tme  [ -c ]  [ -D | -Dn ]  [ macros.tex ... ]  <input.tex  >output.tex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接