【问题标题】:Just got bashed by my sed script- why?刚刚被我的 sed 脚本搞砸了——为什么?
【发布时间】:2023-03-26 15:25:01
【问题描述】:

根据我收到的here 的有用答案,我创建了以下脚本,将其命名为 convert_image_paths.command,将其放入我 Mac 上的网站文件夹中并双击它。

#!/bin/bash

# This script will operate on valid relative image paths at this level and one sub-level down, across .html and .css files.

find . -name "*.css" -o -name "*.html" -exec sed -i '' 's/\.\.\/images\//images\//g' {} ';'
find . -name "*.css" -o -name "*.html" -exec sed -i '' 's/images\//http:\/\/mycdn\.com\/images\//g' {} ';'

不幸的是,它没有将网站中的相对图像路径更改为新的cdn url,而是

  1. 加倍网址:http://mycdn.com/http://mycdn.com/images/myimage.png
  2. 对我机器上的每个 html/css 文件都这样做了

所以我的问题是 a) 是否有白痴标签和 b) 如何修复此脚本?

编辑:

让我澄清一下我的意图: 我想将更改应用于所有具有相对 url 形式的图像路径

“图像/{myimagepath}”

"../images/{myimagepath}"

【问题讨论】:

  • 这就是为什么你使用 -e 进行测试并且只在你知道它有效时才使用 -i 的原因。
  • -e 没有任何关系。不用-i先运行它;这是告诉 sed 编辑文件而不是将结果打印到标准输出的选项。 -e 告诉 sed 下一个参数是要执行的 sed 命令。 sed -e <expr> <path> 完全等价于sed <expr> <path>;它对于运行多个命令非常有用。

标签: macos bash sed


【解决方案1】:

回答你的第二个问题:

b) 不要“查找”。当您不知道脚本从哪个目录开始时。如果您希望它从特定目录开始,请在 find 命令中告诉它:find /Users/ptomblin/Shared/ ...

至于为什么它的 URL 加倍,是因为你告诉它的。

sed -i '' 's/images\//http:\/\/mycdn\.com\/images\//g' {}

获取单词“images/”的每个实例并将其更改为“http://mycdn.com/images/”,即使它已经以“http://mycdn.com/”开头。如果这不是您想要的,您将不得不更具体地了解您的正则表达式。

作为第一次尝试,我会将这两行替换为以下内容

find /Users/ptomblin/Shared -name "*.css" -o -name "*.html" -exec sed -i '' 's@".{0,2}/?images@"http://mycdn.com/images@g' {}

仅当 images../images 以双引号开头时才会替换它们。

【讨论】:

  • 谢谢,那么我如何用“mycdn/images{myimage}”替换“images/{myimage}”而不加倍?
【解决方案2】:

find . 表示“在当前目录中查找” - 因此请确保从您要在其中替换所有内容的目录中运行此命令,或者更改脚本以获取参数:

#!/bin/bash
if [ $# -lt 1 ]; then
    echo "usage: myscript <path>"
fi

find "$@" ...

我对为什么事情加倍的猜测只是它运行了两次;原始脚本中的第二个替换将看到“http://mycdn.com/images”并再次替换图像!这是结合两个替换并同时解决该问题的明显方法:

sed -i 's@"\(\.\./\|\)images/@"http://mycdn.com/images/@g'

匹配开放引号以确保在已经存在 http://... 时不替换,并且可以选择匹配后面的 ../。

我肯定会建议通过在单个文件上调用它来进行测试,并将结果打印到标准输出而不是就地编辑:

sed 's@...@...@' <file>

【讨论】:

  • 非常感谢路径安全代码——虽然我仍然不明白它是如何发生的,因为我从相关目录中定义运行它——至于正则表达式代码,我在问题(见编辑)- 任何好的单行想法?
  • @Yarin:在修复中进行了编辑。 Paul Tomblin 的作品同样出色;我们只是以不同的方式编写模式。他的有点短,如果有不同的可能前缀,我的更容易混淆。
【解决方案3】:

我还弄清楚了为什么我的原始脚本无法识别它的当前目录。在 Mac 上,如果您使用 .command 扩展名命名脚本文件,它就会变成可双击的。但是,当您双击执行它时,它不是从命令行执行,而是将其工作目录更改为用户主目录!

myscript.command:

echo "pwd = `pwd`"

./myscript.command : pwd = 当前目录

myscript.command 双击: pwd = 用户主目录

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 2021-09-22
    • 2012-10-22
    • 2018-11-05
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多