2

我正在尝试使用 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。但是,如果有人有解决方案,我将不胜感激他或她的帮助。

4

2 回答 2

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将匹配文本的函数值替换为命令再次运行。

于 2013-10-05T23:02:49.043 回答
2

这可能对您有用(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 替换该模式。最后,检查当前行是否有进一步的模式情况,必要时重复该过程。

于 2013-10-06T07:57:33.160 回答