
私は Perl を使用して、多くの多言語テキスト ファイルを解析しています。次の 2 つのパターン間でテキストを変更する必要があります。
望ましい変更
たとえば、英語のオリジナルバージョンは次のようになります。
\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
(もちろんグループは削除します)
答え1
\\
は二重引用符で囲みます\
。\\ref
は になり、その後に が続きます\ref
。4 つのバックスラッシュを使用します。\r
ef
for f in *; do
if [[ -d $f ]]; then
perl -ne "print if s/(\\\\ref\{.*?)\}/\1_$f\}/g" $f/SystemRequirements_$f.tex
fi
done
同様に、\a
ベル文字(\x07
)です。
答え2
これは引用符の問題です。変数に二重引用符を使用しています$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