Gewünschte Änderungen

Gewünschte Änderungen

Ich verwende Perl, um viele mehrsprachige Textdateien zu analysieren. Ich muss den Text zwischen zwei Mustern ändern:

Gewünschte Änderungen

Die englische Originalversion sieht beispielsweise so aus:

\label{whatever}
\ref{whatever}
\autoref{whatever}

aber das Zeug zwischen {und }sollte mit dem entsprechenden ISO 639-Sprachcode versehen werden, z. B.

\label{whatever_de}
\ref{whatever_de}
\autoref{whatever_de}

Annahmen für Tests

Gegeben seien die folgenden Dateien:

da/myfile_da.tex
de/myfile_de.tex
el/myfile_el.tex
en/myfile_en.tex

und jede Datei enthält:

\label{some_nice_thing}
\ref{some_nice_thing}
\autoref{some_nice_thing}

Mein Ansatz

Ich kann Ordnernamen als ISO 639-Codes verwenden und eine einfache Schleife durch die Dateien erstellen. Das Folgende sollte einfach die geänderten Zeilen auf der Terminalkonsole ausgeben. Ich werde versuchen, die eigenartigen Ergebnisse, die ich erhalte, anhand eines Beispiels zu erklären:

Arbeiten:\\label\{.*?\}

for f in *; do  if [[ -d $f ]]; then perl -ne "print if s/(\\label\{.*?)\}/\1_$f\}/g"  $f/myfile_$f.tex; fi; done

Funktioniert nicht:\\ref\{.*?\}

for f in *; do  if [[ -d $f ]]; then perl -ne "print if s/(\\ref\{.*?)\}/\1_$f\}/g"  $f/myfile_$f.tex; fi; done

Funktioniert nicht:\\autoref\{.*?\}

for f in *; do  if [[ -d $f ]]; then perl -ne "print if s/(\\autoref\{.*?)\}/\1_$f\}/g"  $f/myfile_$f.tex; fi; done

Beachten Sie, dass dies grep -Prin jedem Fall funktioniert (natürlich auch durch Entfernen von Gruppen).

Antwort1

\\wird \in Anführungszeichen. \\refwird, \refworauf tatsächlich \rfolgt ef. Verwenden Sie vier Backslashs:

for f in *; do
    if [[ -d $f ]]; then
        perl -ne "print if s/(\\\\ref\{.*?)\}/\1_$f\}/g" $f/SystemRequirements_$f.tex
    fi
done

Ähnlich \averhält es sich mit dem Glockenzeichen ( \x07).

Antwort2

Es ist ein Anführungszeichenproblem. Sie verwenden doppelte Anführungszeichen für die $fVariable, aber doppelte Anführungszeichen haben auch andere Auswirkungen. Insbesondere ermöglichen sie das Escapen von Zeichen durch Backslashs, sodass es bei Perl zu folgendem Ergebnis \\kommt :\

$ printf "%s\n" "print if s/(\\label\{.*?)\}/\1_$f\}/g"
print if s/(\label\{.*?)\}/\1_\}/g

Dies führt zu einem Problem mit r, da \rals Return-Zeichen angesehen wird (sieheperlrebackslash) - es wird nicht übereinstimmen r. Verwenden Sie stattdessen einfache Anführungszeichen, die nur für die Variable öffnen:

$ printf "%s\n" 'print if s/(\\label\{.*?)\}/\1_'"$f"'\}/g'
print if s/(\\label\{.*?)\}/\1_\}/g

verwandte Informationen