我正在使用perl解析许多多语言文本文件。我需要在两种模式之间更改文本:
例如,英语原始版本如下所示:
\label{whatever}
\ref{whatever}
\autoref{whatever}
但介于{
和之间的内容}
应以适当的ISO 639语言代码作为后缀,例如
\label{whatever_de}
\ref{whatever_de}
\autoref{whatever_de}
给定以下文件:
da/myfile_da.tex
de/myfile_de.tex
el/myfile_el.tex
en/myfile_en.tex
每个文件包含:
\label{some_nice_thing}
\ref{some_nice_thing}
\autoref{some_nice_thing}
我可以将文件夹名称用作ISO 639代码,并在文件之间创建一个简单的循环。以下内容应仅将更改后的行打印到终端控制台。我将通过示例来解释我得到的特殊结果:
\\label\{.*?\}
for f in *; do if [[ -d $f ]]; then perl -ne "print if s/(\\label\{.*?)\}/\1_$f\}/g" $f/myfile_$f.tex; fi; done
\\ref\{.*?\}
for f in *; do if [[ -d $f ]]; then perl -ne "print if s/(\\ref\{.*?)\}/\1_$f\}/g" $f/myfile_$f.tex; fi; done
\\autoref\{.*?\}
for f in *; do if [[ -d $f ]]; then perl -ne "print if s/(\\autoref\{.*?)\}/\1_$f\}/g" $f/myfile_$f.tex; fi; done
请注意,这grep -Pr
适用于每种情况(当然,删除组)
这是一个报价问题。您正在对$f
变量使用双引号,但是双引号还具有其他含义。特别是,它们允许对字符进行反斜杠转义,因此当它到达Perl时就\\
变成了\
:
$ printf "%s\n" "print if s/(\\label\{.*?)\}/\1_$f\}/g"
print if s/(\label\{.*?)\}/\1_\}/g
这就产生了一个问题r
,因为\r
它将被视为返回字符(请参阅perlrebackslash
)-它将不匹配r
。而是使用单引号,仅将变量打开:
$ printf "%s\n" 'print if s/(\\label\{.*?)\}/\1_'"$f"'\}/g'
print if s/(\\label\{.*?)\}/\1_\}/g
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句