【问题标题】:Using sed in bash script to replace LaTeX aliases在 bash 脚本中使用 sed 替换 LaTeX 别名
【发布时间】:2013-07-21 13:21:04
【问题描述】:

我对 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$}

【问题讨论】:

  • 您提供了两个输入文件。好的。现在添加想要的输出。更容易了解您的需求。
  • 所需的输出是用 infile 中的长格式替换所有快捷方式,使其看起来像这样 code这是我的测试 {$^{18}$O} @ 987654327@{$^{18}$O/$^{16}$O} 我的测试是这样的 code它是否有效 {\begin{equation}} code{\begin{eqnarray}} test test test @ 987654330@work work work {C$_3$} code{C$_4$} 这是我的测试code我的测试是这个{CO$_2$}

标签: bash sed latex variable-substitution


【解决方案1】:

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

【讨论】:

  • 我想知道您能否解释一下 sed 命令的工作原理?我已经经历过了,但我无法完全弄清楚。在这种情况下,“#”是什么意思?它与 -r 标志有关吗?我明白 /^%/d;是说如果该行以 % 开头,请跳过它但是我无法理解正文,您能提供任何澄清吗?
  • @user2460253 请看我的回答。我使用# 作为/ 的替代品,以启用带有sed 自身的sed 脚本的构建。如果它适合你,请接受我的回答:Accepting Answers: How does it work?--thanks :)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    但是,为了他人的利益,如果您不坚持使用 bash 和 sed,则存在其他选项可以解决您的问题,例如perl 脚本TME(如建议的here 在SO 上)。用法:

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

    【讨论】:

      猜你喜欢
      • 2020-09-22
      • 2017-11-09
      • 2021-09-12
      • 2013-04-30
      • 2022-07-21
      • 2010-11-29
      • 2014-06-08
      • 2017-09-06
      • 1970-01-01
      相关资源
      最近更新 更多