【问题标题】:How to prepend lines with variables through find, exec and sed?如何通过 find、exec 和 sed 在行前添加变量?
【发布时间】:2018-10-09 18:41:14
【问题描述】:

我无法将之前在论坛上回答的部分相似问题的不同建议和答案结合起来,所以我会问我自己的问题,希望有人可以分享解决这个问题的想法:-)

所以这里是项目:

  • 我有很多 .tex 文件
  • 我正在使用一种元数据将它们重组为更好的管理(系统化)系统
  • 他们都应该有我想要重塑的标记线。

输入文件如下所示:

\section{the title}
\status{Work in progress}

content

标题显然各不相同,状态从“待办事项”到“正在进行的工作”和“已写”不等。

需要的输出:

\renewcommand{\TITLE}{the title}
\renewcommand{\STATUS}{\Doing}

\section{\TIT}

\STA

content

合成

  • 标题需要保持不变(这就是我想我需要一个变量的原因)
  • 状态需要标准化
  • 部分前置文本已系统化

有什么想法吗? :-)

【问题讨论】:

  • 你用 sed 试过了吗?
  • 是的,因为我有一堆目录和文件,我从find -name '*tex' -exec sed '/status|section/p' {} + 开始获取这些事件,但我不知道之后该怎么做才能将它们重新插入第一行
  • 学习修改一个文件,然后再尝试修改所有个文件。
  • 进一步扩展,你有四个独立的问题。 1) 修改section 行,2) 修改status 行并添加几行,3) 将修改保存到文件中,4) 一次对所有的tex 文件进行操作。您应该分别尝试所有四个,然后向我们寻求帮助以解决您遇到的问题。
  • 好的,谢谢你的建议,我会保持联系

标签: bash sed find latex


【解决方案1】:

正如@Beta 所建议的,您可能应该将您的问题分解为几个可以独立解决的子问题。让我们首先找到一种方法来转换部分,然后是状态,然后将两者结合起来,最后但并非最不重要的是,将所有这些结合起来以在多个文件上运行。

转换标题(一个文件)

我们可以使用sed 来检测section 并将它们转换成两行:renewcommand 和new section。

sed -r 's/\\section\{([^}]+)\}/\\renewcommand{\\TITLE}{\1}\n\\section{\\TIT}/g'

它是这样工作的:

echo '\section{The title}' | sed -r 's/\\section\{([^}]+)\}/\\renewcommand{\\TITLE}{\1}\n\\section{\\TIT}/g' 

将导致:

\renewcommand{\TITLE}{The title}
\section{\TIT}

转换状态(一个文件)

我们可以对状态应用一个非常相似的转换:

sed -r 's/\\status\{([^}]+)\}/\\renewcommand{\\STATUS}{\1}\n\\STA/g'

会发生什么变化:

\status{Work in progress}

进入:

\renewcommand{\STATUS}{Work in progress}
\STA

结合两者(一个文件)

现在您可以轻松地在给定文件上一个接一个地应用一个 sed:

sed -ir \
  -e 's/\\status\{([^}]+)\}/\\renewcommand{\\STATUS}{\1}\n\\STA/g' \
  -e 's/\\section\{([^}]+)\}/\\renewcommand{\\TITLE}{\1}\n\\section{\\TIT}/g' filename.tex

这会将两个转换都应用到filename.tex 并就地更改它。

应用于多个文件

现在您可以使用findxargs 对文件夹中的所有文件(递归)应用此sed 命令,以在每个文件上调用该命令:

find . -name '*.tex' -print0 | xargs -0 -I{} sed -ri  \
  -e 's/\\status\{([^}]+)\}/\\renewcommand{\\STATUS}{\1}\n\\STA/g' \
  -e 's/\\section\{([^}]+)\}/\\renewcommand{\\TITLE}{\1}\n\\section{\\TIT}/g' {}

find . -name '*.tex' -print0 将递归列出所有tex 文件。然后| xargs -0 -I{} command {} 将对每个单独的文件调用command

我会确保您在尝试进行此类转换之前备份(或版本控制)所有文件。只是为了确保在出现问题时可以回滚。

我希望这会有所帮助。

【讨论】:

  • 它需要一步一步的find -exec sed 来准备每个文档,这样它们的结构就很直接了,而且工作得很好!谢谢!
猜你喜欢
  • 2016-11-09
  • 2023-03-27
  • 2018-09-20
  • 1970-01-01
  • 2023-02-10
  • 2019-12-11
  • 2019-04-09
  • 2017-12-09
相关资源
最近更新 更多