Cambios deseados

Cambios deseados

Estoy usando Perl para analizar muchos archivos de texto multilingües. Necesito cambiar el texto entre dos patrones:

Cambios deseados

Por ejemplo, la versión original en inglés se ve así:

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

pero las cosas entre {y }deben tener el sufijo del código de idioma ISO 639 apropiado, por ejemplo

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

Supuestos para las pruebas

Dados los siguientes archivos:

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

y cada archivo contiene:

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

Mi acercamiento

Puedo usar nombres de carpetas como mis códigos ISO 639 y crear un bucle simple a través de los archivos. Lo siguiente simplemente debería imprimir las líneas modificadas en la consola del terminal. Intentaré explicar los resultados peculiares que obtengo con ejemplos:

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

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

No funciona:\\ref\{.*?\}

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

No funciona:\\autoref\{.*?\}

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

Tenga en cuenta que grep -Prfunciona con cada caso (eliminando grupos, por supuesto)

Respuesta1

\\se convierte \en comillas dobles. \\refse convierte \refen lo que de hecho es \rseguido por ef. Utilice cuatro barras invertidas:

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

De manera similar, \aes el carácter BELL ( \x07).

Respuesta2

Es un problema de cotización. Estás utilizando comillas dobles para la $fvariable, pero las comillas dobles también tienen otras implicaciones. En particular, permiten el escape de caracteres con barra invertida, lo que \\ocurre \cuando llega a Perl:

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

Esto crea un problema con r, porque \rserá visto como el carácter de retorno (verperlrebackslash) - no coincidirá r. Utilice comillas simples en su lugar, abriéndose solo para la variable:

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

información relacionada