Сед дает: sed: не может читать: нет такого файла или каталога

У меня есть следующий bash script, который повторяется для каждого найденного изображения. Он должен быть повторен по всем файлам html, css и js и заменять все вхождения изображения внутри этого файла.

 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

Однако, когда я запускаю script sed, выдает:

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

В StackOverflow я нашел sed: не могу прочитать: нет такого файла или каталога Но у меня уже были цитаты вокруг {}

Когда я повторяю команду sed и выполняю ее в командной строке вручную, ошибки не возникает.

Я использую GNU sed v4.2.2 для Raspbian GNU/Linux 8.0 (jessie)

Кто-нибудь видит, что здесь может быть неправильно?

Ответ 1

(Компиляция ответа с комментариями, ноу-хау - с помощью melpomene и AlexP.)

Что это за '' после sed -i?

-i означает на месте, то есть редактировать в файле напрямую.
-i '' означает редактирование на месте файла, чье имя является пустой строкой.
Поскольку, вероятно, нет файла, чье имя является пустой строкой, sed жалуется, что он не может его прочитать.

Примечание 1 зависимость от платформы:
Синтаксис -i - это одно отличие между GNU sed и sed от mac os.

Примечание 2 "обычный" порядок аргументов:
Переключатель -e указывает, что sed-код позволяет использовать его между именами файлов.
Это ловушка (в которой я, например, попал в замешательство), заставив вас отправиться в путешествие по вашим ожиданиям от того, что вы найдете там, где в командной строке sed.
Это позволяет sed -i filename -e "expression" AnotherFileName
которая является непреднамеренно замаскированной версией sed -i'NoExtensionGiven' "expression" filename AnotherFileName.

Ответ 2

Для поддержки как 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