望ましい変更

望ましい変更

私は 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 つのバックスラッシュを使用します。\ref

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

関連情報