4

我对 bash 脚本比较陌生,对 LaTeX 没有经验。我被要求开发一个脚本,将 LaTeX 文档中的便捷快捷方式替换为更繁琐的长格式等价物。

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

由于目前该脚本采用 2 个参数,一个文件 expr 从中检索快捷方式和长格式术语,以及一个应该对其进行适当更改的 infile。我知道该脚本正确隔离了快捷方式和长格式并可以返回它们,但它似乎无法执行 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$}

infile 包含要替换为长格式的快捷方式

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$}
4

3 回答 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

$猫文件1
% 一种
\新命令{\ao}{$^{18}$O}
\newcommand{\aodso}{$^{18}$O/$^{16}$O}
% b
\newcommand{\bea}{\begin{方程}}
\newcommand{\beaa}{\begin{eqnarray}}
% C
\newcommand{\cthree}{C$_3$}
\newcommand{\cfour}{C$_4$}
\newcommand{\coz}{CO$_2$}

$猫文件2
这是我的测试 {\ao}
{\aodso} 我的测试是这样的
有用吗{\bea}
{\beaa} 测试测试测试
工作工作工作 {\cthree}
{\cfour} 这是我的测试
我的测试是这个 {\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#' 文件1
\|{\\ao}|s|{\\ao}|{$^{18}$O}|g
\|{\\aodso}|s|{\\aodso}|{$^{18}$O/$^{16}$O}|g
\|{\\bea}|s|{\\bea}|{\\begin{方程}}|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
于 2013-07-22T19:38:46.353 回答
1

在 tex.SE上有很多关于这个问题的讨论但我会借此机会指出,那里的最佳答案(IMO)是使用该de-macro程序,它是 TeXLive 附带的 python 脚本。它非常有能力,可以处理参数以及简单的替换。

要使用它,请将要扩展的宏移动到 <something>-private.sty文件中,并使用 将其包含到文档中\usepackage{<something>-private},然后运行de-macro <mydocument>​​. 它吐出<mydocument>-private.tex,这与您的原始内容相同,但您的私有宏被它们更基本的东西所取代。

于 2016-04-19T15:47:11.957 回答
0

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

但是,为了其他人的利益,如果您不坚持使用 bash 和 sed,那么还有其他选项可以解决您的问题,例如 perl 脚本TME(如这里所建议的那样)。用法:

tme  [ -c ]  [ -D | -Dn ]  [ macros.tex ... ]  <input.tex  >output.tex
于 2014-06-03T08:07:30.230 回答