min*_*nto 0 bash debian sed shell-script html
我需要替换目录中多个 xhtml 文件中图像的路径。文件头部分如下:
<?xml version="1.0" encoding="UTF-8"?>
<html xml:lang="en-us" lang="en-us" xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:ns="http://www.w3.org/2001/10/synthesis">
<head>
Run Code Online (Sandbox Code Playgroud)
尝试用命令来完成sed,但没有成功。可能是由于特定的 sed 版本,但不确定。我有GNU sed 4.4
original path:
<img src="/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"
I need replace to:
<img src="graphics/line.jpg"
Run Code Online (Sandbox Code Playgroud)
我试过
sed -i '.bak' 's/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g' '*.xhtml'
Run Code Online (Sandbox Code Playgroud)
它返回
sed: -e expression #1, char 1: unknown command: `.'
Run Code Online (Sandbox Code Playgroud)
也尝试过
sed -i ' ' 's/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g' '*.xhtml'
it return
sed: can't read s/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g: No such file or directory
sed: can't read *.xhtml: No such file or directory
Run Code Online (Sandbox Code Playgroud)
适合sed这个吗?
该sed实用程序通常不适合编辑 XML 或 XHTML 文件。XML 是一种结构化文档格式,不是面向行的。与许多标准 Unix 文本操作工具一样,该sed实用程序是面向行的,并且不需要额外的努力就无法处理 XML 实体的编码或解码之类的事情。
您的示例文档包含节点(已更正为包含/>在末尾)
<img src="/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg" />
Run Code Online (Sandbox Code Playgroud)
由于节点内的空白(空格、制表符和换行符)是任意的,并且我们不知道节点的更多属性img或其顺序,因此使用sed. src我们还必须确保除了节点属性中的路径名之外,不要在其他任何地方替换路径名img。
使用命令行 XML 解析器来执行此操作可能如下所示:
xmlstarlet ed \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg' file.xhtml
Run Code Online (Sandbox Code Playgroud)
我们使用xmlstarlet,一个相当知名的命令行 XML 解析器,如果属性的原始值为 ,则用字符串替换每个节点src的每个属性的值。imggraphics/line.jpg/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg
该命令将操作结果写入标准输出,但您可以在测试后使用其(或) 选项xmlstarlet进行就地编辑,以确保它看起来像您期望的那样工作。--inplace-L
如果您的img标签看起来像<img src="...">, 没有正确的结尾,那么您可以通过首先过滤您的 XHTML 文件来恢复此情况
xmlstarlet fo --recover --html file.xhtml
Run Code Online (Sandbox Code Playgroud)
人们甚至可以设想表单上有一条管道
xmlstarlet fo --recover --html file.xhtml |
xmlstarlet ed \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg'
Run Code Online (Sandbox Code Playgroud)
如果您要处理的文件全部匹配模式./*.xhtml,即,如果它们具有.xhtml文件名后缀并且位于当前目录中,那么您将能够使用简单的 shell 循环使用上述命令中的任何一个来处理所有这些文件。
for name in ./*.xhtml; do
xmlstarlet ed --inplace \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg' "$name"
done
Run Code Online (Sandbox Code Playgroud)
请注意,这使用--inplace的选项xmlstarlet,该选项将修改文件而不进行备份。如果您在备份数据上运行此操作,那就最好了。
要对目录层次结构(即具有多个子目录的目录)中的所有 XHTML 文件运行上述命令,您可以使用find.
find . -type f -name '*.xhtml' -exec sh -c '
for name do
xmlstarlet ed --inplace \
-u "//img/@src[. = \"/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg\"]" \
-v "graphics/line.jpg" "$name"
done' sh {} +
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1575 次 |
| 最近记录: |