【问题标题】:Sed dynamic backreference replacementSed 动态反向引用替换
【发布时间】:2013-10-05 22:35:39
【问题描述】:

我正在尝试使用 sed 将 wikitext 转换为乳胶代码。我快完成了,但我想自动生成这样的数字标签:

[[Image(mypicture.png)]]

...进入:

\includegraphics{mypicture.png}\label{img-1}

我想继续使用 sed。我正在使用的当前正则表达式和 bash 代码如下:

__tex_includegraphics="\\\\includegraphics[width=0.95\\\\textwidth]{$__images_dir\/"
__tex_figure_pre="\\\\begin{figure}[H]\\\\centering$__tex_includegraphics"
__tex_figure_post="}\\\\label{img-$__images_counter}\\\\end{figure}"

sed -e "s/\[\[Image(\([^)]*\))\]\].*/$__tex_figure_pre\1$__tex_figure_post/g"\

...但我不能让那个计数器增加。有什么想法吗?

从更一般的角度来看,我的问题如下:我可以在 sed 中使用反向引用来创建对 sed 的每个匹配项都不同的替换吗?也就是说,每次sed匹配模式时,我可以使用\1作为函数的输入,并使用这个函数的结果作为替换吗?

我知道这是一个棘手的问题,我可能不得不为此使用 AWK。但是,如果有人有解决方案,我会很感激他或她的帮助。

【问题讨论】:

  • 我会选择输出包含乳胶计数器的静态乳胶代码,并在标签中使用来自该计数器的值。这样乳胶以后更易于维护。

标签: regex bash unix sed awk


【解决方案1】:

这可能对你有用(GNU sed):

sed -r ':a;/'"$PATTERN"'/{x;/./s/.*/echo $((&+1))/e;/./!s/^/1/;x;G;s/'"$PATTERN"'(.*)\n(.*)/'"$PRE"'\2'"$POST"'\1/;ba}' file

这会查找包含在 shell 变量中的 PATTERN,如果不存在则打印当前行。如果模式存在,它会增加或初始化保持空间中的计数器,然后将所述计数器附加到当前行。然后使用 shell 变量 PRE 和 POST 和 counter 替换该模式。最后,检查当前行是否有更多的模式案例,并在必要时重复该过程。

【讨论】:

  • 肯定比我预期的要复杂。感谢您的帮助。
【解决方案2】:

您可以使用 shell 功能逐行读取文件,并为每一行使用单独的 sed 命令。类似的东西

exec 0<input_file

while read line; do
    echo $line | sed -e "s/\[\[Image(\([^)]*\))\]\].*/$__tex_figure_pre\1$__tex_figure_post/g"
    __images_counter=$(expr $__images_counter + 1)
done

(不过,如果一行中有多个匹配项,这将不起作用。)

对于第二部分,我最好的想法是运行sedgrep 来查找匹配的内容,然后再次运行sed,并将匹配文本的函数值替换到命令中。

【讨论】:

  • read line 将修改带有反斜杠的行。使用read -r。更好的是IFS= read line,它不会从行尾修剪空白。 echo $line 将删除前导空格并将所有其他空格更改为单个空格,并且如果在某些行中有松散的*,也会做一些非常讨厌的事情。使用echo "$line"。除此之外,这是个不错的建议,但实际上 sed 和 bash 都不是适合这项工作的工具。
  • Okey... 所以,最后,sed 本身并不支持我想要的。感谢您的解决方案。
猜你喜欢
  • 2019-11-16
  • 1970-01-01
  • 2022-01-27
  • 2019-11-29
  • 2019-01-04
  • 2021-08-13
  • 1970-01-01
  • 2015-08-29
  • 2011-12-25
相关资源
最近更新 更多