недопустимый код команды., несмотря на экранирование, используя sed

187

Будучи вынужденным использовать CVS для текущего клиента, а адрес изменился для удаленного репо. Единственный способ найти удаленный адрес в моем локальном коде - это рекурсивный поиск и замена.

Тем не менее, с командой sed я ожидал работать:

find ./ -type f -exec sed -i "s/192.168.20.1/new.domain.com/" {} \;

Я получаю сообщение об ошибке для каждого файла:

sed: 1: ".//file/path ...": invalid command code .

Я пытался избежать периодов в Sed Match / замене, но это ничего не решает.

helion3
источник

Ответы:

476

Если вы работаете в OS X, это, вероятно, не имеет ничего общего с командой sed. По версии OSX из sed, то -iвариант ожидает extensionаргумент , так ваша команда на самом деле разобрана в качестве extensionаргумента , и путь к файлу интерпретируются как код команды.

Попробуйте -eявно добавить аргумент и указать в ''качестве аргумента -i:

find ./ -type f -exec sed -i '' -e "s/192.168.20.1/new.domain.com/" {} \;

Смотрите это .

damienfrancois
источник
41
Если вы потратили 10 минут, как я нашел разницу, это опция -e
acheron55
9
Этот вопрос отвечает RE error: illegal byte sequenceна MacOS.
JonasVautherin
11
я использовал пустую строку '' в качестве параметра для -i, и это сработало, напримерsed -i '' 's/blah/xx/g'
Пьер Хьюстон
25
Для меня, добавив -eпосле того, как -iсделал sedрезервную копию всех моих файлов таким образом: "foo.txt" -> "foo.txt-e". Очевидно, что я хотел, а -i ''не делать резервные копии измененных файлов.
mdup
3
Та же проблема для меня. Это привело -i -eк findтому, что многие файлы заканчивались на -e-e-e-e-e-e-e.
аспирация
39

Вы просто забыли предоставить аргумент -i. Просто измени -iна -i ''.

Конечно, это означает, что вы не хотите, чтобы резервные копии ваших файлов; в противном случае поставьте ваше расширение выбора, как -i .bak.

mdup
источник
6

На OS X ничто не помогает бедному встроенному sedу стать адекватным. Решение:

brew install gnu-sed

А затем используйте gsed вместо sed, который будет работать как положено.

Дмитрий Микушин
источник
1
Спасибо за этот ответ, который отлично сработал для меня! Работая как на Linux, так и на Mac, я бы предпочел доступ к знакомому инструменту, чем изучать тайные различия между двумя тесно связанными.
Стивен Шенк
3

Возможно, ваш новый домен содержит /? Если это так, то попробуйте использовать разделитель, кроме /в sed, например #, и ,т.д.

find ./ -type f -exec sed -i 's#192.168.20.1#new.domain.com#' {} \;

Также было бы хорошо заключить s///в одинарные кавычки, а не в двойные кавычки, чтобы избежать подстановки переменных или любого другого непредвиденного поведения.

jkshah
источник