首页 > 解决方案 > 如何用 sed 或 awk 替换子字符串中的字符?

问题描述

我需要从 HTML 文档中的某些文件名(并且只有文件名)中替换特殊字符。我知道如何用or替换整个文本中的特殊字符,我知道如何用(例如)用另一个给定的字符串替换文件名,但我不确定能否以某种方式匹配我输入的字符?trsedsed's,src="\([^"]*\)",src="newprefixtofilename_\1"'sed\1

如果sed无法做到这一点,我该怎么做awk?可能可以隔离"带有前缀的分隔字符串并仅对这些字符串src=进行 a 。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"

标签: bashsedreplace

解决方案


你不能sed直接这样做(不知道awk,tho)。首先,您需要创建一个辅助文件,在其中将每个字符替换为 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"

推荐阅读