Сед дает: 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