代码之家  ›  专栏  ›  技术社区  ›  Yarin

刚刚被我的SED脚本击伤了-为什么?

  •  0
  • Yarin  · 技术社区  · 14 年前

    根据我收到的有用答案 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/我的图像路径”

    3 回复  |  直到 14 年前
        1
  •  4
  •   Paul Tomblin    14 年前

    回答第二个问题:

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

    至于为什么它把网址翻了一番,那是因为你告诉它的。

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

    获取单词“images/”的每个实例,并将其更改为“http://mycdn.com/images/”,即使它已经以“http://mycdn.com/”开头。如果这不是你想要的,你必须对你的regexp更加具体。

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

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

    那只会取代 images ../images 如果以双引号开头。

        2
  •  1
  •   Cascabel    14 年前

    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://…的情况下不进行替换,并且可以选择在其后面匹配../。

    我绝对建议通过在单个文件上调用这个测试,结果打印到stdout,而不是就地编辑:

    sed 's@...@...@' <file>
    
        3
  •  1
  •   Yarin    14 年前

    我还弄明白了为什么我的原始脚本不能识别它的当前目录。在macs上,如果用.command扩展名命名一个脚本文件,它将变成可双击的。然而, 双击执行时 ,而不是从命令行, 将其工作目录更改为用户主目录!

    myscript.命令:

    echo "pwd = `pwd`"
    

    /myscript.command: pwd=当前目录

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