Желаемые изменения

Желаемые изменения

Я использую perl для разбора множества многоязычных текстовых файлов. Мне нужно изменить текст между двумя шаблонами:

Желаемые изменения

Например, оригинальная версия на английском языке выглядит так:

\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которым на самом деле \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есть символ BELL ( \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

Связанный контент