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

У меня есть следующее bash скрипт, который повторяется для каждого найденного изображения. Он должен перебирать все файлы 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

Однако когда я запускаю скрипт sed дает:

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

В Stackru я нашел sed: not read: Нет такого файла или каталога, но у меня уже были кавычки {}

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

Я использую GNU sed v4.2.2 на Raspbian GNU/Linux 8.0 (Джесси)

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

4 ответа

Решение

(Составляя ответ из комментариев, ноу-хау от 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,

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

В своих сценариях bash я использую что-то вроде этого (для поддержки дистрибутивов MacOS и Linux):

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

sed $SEDOPTION "/^*/d" ./file

У меня это решилось перезапуском

      wsl --shutdown
Другие вопросы по тегам