Как заменить символы в подстроке с помощью sed или awk? - PullRequest
0 голосов
/ 22 октября 2019

Мне нужно заменить специальные символы из некоторых имен файлов (и только имен файлов) в документе HTML. Я знаю, как заменить специальные символы в тексте целом на tr или sed, я знаю, как заменить имя файла другой данной строкой на sed (например, 's,src="\([^"]*\)",src="newprefixtofilename_\1"'), ноЯ не уверен, что sed может каким-то образом соответствовать символам внутри того, что я получаю в \1?

Если sed не может сделать это, как я могу это сделать, например, с awk? Вероятно, можно выделить строки " с разделителями, которые начинаются с src=, и использовать только gsub для них. Я могу предположить, что src= появляется только в тегах (поэтому нет «реального» разбора html) и что для каждой строки файла соответствует только одна строка.

Пример строки ввода:

  <img src="spécial.png"> Spécial
  <img src="piètre.png"> Some text including "piètre"

Требуемый вывод с [éî] замененным на [ei] только в именах файлов:

 <img src="special.png"> Spécial
 <img src="pietre.png"> Some text including "piètre"

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Вы не можете сделать это с sed напрямую (не знаю о awk, хотя). Сначала вам нужно создать вторичный файл, в котором вы заменяете каждый символ на символ UTF8, затем анализируете и заменяете различия.

Я настоятельно рекомендую сначала попробовать его на тестовых данных.

# Translate non UTF8
$ iconv -f utf-8 -t ascii//translit files.html > tmp.txt

# Create arrays (IFS if files have spaces, otherwise redundant)
$ IFS=$'\n'
$ FROM=($(diff files.html tmp.txt | grep '^<.*<img' | sed -r 's/.*src="([^"]*)".*/\1/'))
$ TO=($(diff files.html tmp.txt | grep '^>.*<img' | sed -r 's/.*src="([^"]*)".*/\1/'))

# Rename files (mv spécial.png special.png)
$ for ((i=0; i < ${#FROM[@]}; i++)); do mv "${FROM[$i]}" "${TO[$i]}"; done

# Change html src attributes
$ for ((i=0; i < ${#FROM[@]}; i++)); do sed -i "s/${FROM[$i]}/${TO[$i]}/" files.html; done

# End result
$ cat files.html 
<img src="special.png"> Spécial
<img src="pietre.png"> Some text including "piètre"
1 голос
/ 23 октября 2019

Указание требования: заменить специальный символ (é-> e, î-> i) только внутри токенов src = "...".

Предполагается, что файлы XML отформатированы разумно (более конкретно,полный тег IMG находится в одной строке), можно добиться, заменив каждый из специальных символов с помощью команды 's'.

First line é->e, second line î->i
sed -e 's,src="\([^"]*\)é\([^"]*"\),src=\1e\2,g' \
    -e 's,src="\([^"]*\)î\([^"]*"\),src=\1i\2,g'

Приведенное выше решение не будет обрабатывать src, который имеет одни и те же специальные символы более одного раза,(Например, src- "xîzîtîFi.png". Если это проблема, и предполагается, что в приведенном ниже примере принимается небольшое количество повторов 92, то

   # é->e 
sed -e 's,src="\([^"]*\)é\([^"]*"\),src="\1e\2,g' \
  -e 's,src="\([^"]*\)é\([^"]*"\),src="\1e\2,g' \
  -e 's,src="\([^"]*\)é\([^"]*"\),src="\1e\2,g' \
  -e 's,src="\([^"]*\)î\([^"]*"\),src="\1i\2,g' \
  -e 's,src="\([^"]*\)î\([^"]*"\),src="\1i\2,g' \
  -e 's,src="\([^"]*\)î\([^"]*"\),src="\1i\2,g'

Я уверен, что есть возможностьиспользование меток / ветви для выполнения вышеуказанной замены более выгодно для обработки неограниченного количества специальных символов.

Переименование файлов Другой вопрос может использовать команду «sed» Transliterate. Что-то вроде:

for file in FILELIST ; do
  new_name=$(echo $file | sed -e 'y/éî/ei/')
  if [ "$file" != "$new_name] ; then
    mv $file $new_name
  if
done
...