Невозможно заменить текст с помощью sed

Я сделал это. Я создаю новый файл (с суффиксом at «.new»), но перед заменой старого я проверяю разницу в размерах файлов и прерываю (отправляя какое-либо уведомление, например по почте), если изменений слишком много.

Я обычно делаю это на perl, но bash будет похож.

$file="file_being_updated";
$new=".new";

if ( -f $file ) {
  my $percent_diff = abs( 100 - 100*(-s "$file$new")/(-s $file) );
  if (  $percent_diff > 20 ) {   # more that this to different!
    printf STDERR "File \"$file$new\" differs by more that 20%%! (%.1f%%)\n",  $percent_diff;
    printf STDERR "-------------- ABORTING REPLACMENT -----------\n";
    exit 10;
  }
}
0
20.11.2018, 22:21
2 ответа

Я бы порекомендовал что-то более похожее на следующее:

sed -i 's|$DEFAULT_MAIL_DOMAIN = \"padl.com\";|$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\";|' /usr/share/migrationtools/migrate_common.ph

Изменения, которые я сделал:

  • изменено на одинарные кавычки вокруг замены sed. Все эти двойные кавычки, которые вы использовали, должны были вызвать проблемы.
  • Изменено с / на | для синтаксиса подстановки sed. Эта часть не нужна. Я просто предпочитаю это. Вы можете оставить /, если хотите.
  • Затем я удалил двойные кавычки вокруг текста поиска и замены. В них не было нужды.
  • Экранированные двойные кавычки, которые на самом деле находятся в тексте файла.
  • удалил глобальный флаг в конце подстановки sed. Это выглядит как параметр в конфигурационном файле, это происходит только один раз в строке (и, возможно, один раз в файле).
4
28.01.2020, 02:15

Если $DEFAULT_MAIL_DOMAIN и кавычки являются буквальной частью файла, нам нужно использовать одинарные кавычки или обратную косую черту, чтобы избежать их. Итак, одно из следующего:

$ E_DOMAIN=foobar.com
$ sed -e 's/$DEFAULT_MAIL_DOMAIN = "padl.com"/$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/' file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
...
$ sed -e "s/\$DEFAULT_MAIL_DOMAIN = \"padl.com\"/\$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\"/" file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";

В первом случае кавычки интерпретируются следующим образом:

'.../$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^           ^^^^  - single-quoted, literal ""s
                              ^^^^^^^^^^^  - double-quoted, var expanded

Во втором все это представляет собой строку в двойных кавычках с проблемными $ и " экранировано. Но не $ в $E_DOMAIN, так как мы хотим расширить эту переменную.

Я не уверен, что переменная должна быть E_DOMAIN или E_DOMAIN_VAR, вы добавили суффикс .com к последнему, но использовали первый в команде sed. В любом случае, /, & или новая строка в переменной будут специально обработаны sed, но доменное имя не должно их содержать


. цитирование немного смещено:

sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" 

Первая часть "s/" является строкой в ​​кавычках, затем $DEFAULT_MAIL_DOMAIN находится вне кавычек, поэтому раскрывается как переменная (вероятно, до пустой строка). Пробелы также не заключены в кавычки, поэтому sed получает несколько аргументов, и, вероятно, будет жаловаться. "padl.com" снова заключен в кавычки, но точка с запятой отсутствует, поэтому оболочка интерпретирует ее как завершение команды.

2
28.01.2020, 02:15

Теги

Похожие вопросы