Mudanças desejadas

Mudanças desejadas

Estou usando Perl para analisar muitos arquivos de texto multilíngues. Preciso alterar o texto entre dois padrões:

Mudanças desejadas

Por exemplo, a versão original em inglês é assim:

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

mas o material entre {e }deve ser sufixado com o código de idioma ISO 639 apropriado, por exemplo

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

Suposições para teste

Dados os seguintes arquivos:

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

e cada arquivo contém:

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

Minha abordagem

Posso usar nomes de pastas como meus códigos ISO 639 e criar um loop simples pelos arquivos. O seguinte deve simplesmente imprimir as linhas alteradas no console do terminal. Tentarei explicar os resultados peculiares que estou obtendo através de exemplos:

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

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

Não está funcionando:\\ref\{.*?\}

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

Não está funcionando:\\autoref\{.*?\}

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

Observe que grep -Prfunciona com cada caso (removendo grupos, é claro)

Responder1

\\fica \entre aspas duplas. \\reftorna-se \refo que é de fato \rseguido por ef. Use quatro 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

Da mesma forma, \aé o caractere BELL ( \x07).

Responder2

É um problema de cotação. Você está usando aspas duplas para a $fvariável, mas aspas duplas também têm outras implicações. Em particular, eles permitem o escape de caracteres com barra invertida, o que \\acontece \quando chega ao Perl:

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

Isso cria um problema com r, porque \rserá visto como o caractere de retorno (vejaperlrebackslash) - não corresponderá r. Use aspas simples, abrindo apenas para a variável:

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

informação relacionada