59

我有以下bash脚本,它对找到的每个图像重复。它需要遍历所有htmlcssjs文件,并替换该文件中所有出现的图像。

 for image in app/www/images-theme-dark/*.png
    do
        echo "installing icon" $image

        # extract filename from iconpath
        iconfile=$(basename $image)
        iconPath="images/"$(basename $image)

        # replace paths in all files containing icon paths
        find app/www -type f \( -name "*.html" -or -name "*.css" -or -name "*.js" \
                            -or -name "*.appcache" \)  \
            -exec sed -i '' -e 's|$iconPath|images-theme-dark/$iconfile|g' "{}" \;

    done

但是,当我运行脚本时sed

sed: can't read : No such file or directory

在 StackOverflow 上我发现sed: can't read : No such file or directory但我已经引用了{}

当我回显sed命令并在命令行上手动执行它时,没有错误。

我在 Raspbian GNU/Linux 8.0 (jessie) 上使用 GNU sed v4.2.2

有人看到这里可能出了什么问题吗?

4

3 回答 3

99

根据评论编写答案,诀窍是 melpomene 和 AlexP。

''之后是什么sed -i

-i表示就地,即直接在文件中编辑。
-i '' 表示就地编辑名称为空字符串的文件。
由于可能没有名称为空字符串的文件,sed 抱怨它无法读取它。

注意 1平台依赖性
的语法-i是 GNU sed 和 mac os 中的 sed 之间的一个区别。

注意 2 “通常”的参数顺序:指示 sed 代码
-e开关允许将其放在文件名之间。
这是一个陷阱(例如,我被困在其中),使您超出了对在 sed 命令行中找到的内容的期望。
它允许
sed -i filename -e "expression" AnotherFileName
这是一个无意伪装的
sed -i'NoExtensionGiven' "expression" filename AnotherFileName.

于 2017-04-17T14:29:46.800 回答
67

为了同时支持 OSX 和 Linux,我使用了一个简单的 if 检查来查看 bash 脚本是否在 OSX 或 Linux 上运行,并-i据此调整命令的参数。

if [[ "$OSTYPE" == "darwin"* ]]; then
  sed -i '' -e 's|$iconPath|images-theme-dark/$iconfile|g' "{}"
else
  sed -i -e 's|$iconPath|images-theme-dark/$iconfile|g' "{}"
fi
于 2019-09-03T07:16:06.887 回答
3

在我的 bash 脚本中,我使用了类似的东西(同时支持 MacOS 和 Linux 发行版):

SEDOPTION=
if [[ "$OSTYPE" == "darwin"* ]]; then
  SEDOPTION="-i ''"
fi

sed $SEDOPTION "/^*/d" ./file
于 2021-03-23T13:03:32.370 回答