Подтвердить что ты не робот

Код возврата sed для бездействия

Я использую sed для обновления моего конфигурационного файла json во время выполнения. Иногда, когда шаблон не соответствует в json файле, все еще sed завершается с кодом возврата 0.

Возврат 0 означает успешное завершение, но почему sed возвращает 0, если он не находит правильный шаблон и не обновляет файл? Есть ли обходной путь для этого?

Спасибо!

4b9b3361

Ответ 1

как комментирует @cnicutar, код возврата команды означает, что команда выполнена успешно. не имеет ничего общего с логикой, которую вы реализовали в кодах/сценариях.

так что если у вас есть:

echo "foo"|sed '/bar/ s/a/b/'

sed вернет 0, но если вы напишете некоторые ошибки синтаксиса/выражения или вход/файл не существует, sed не сможет выполнить ваш запрос, sed вернет 1.

обходной путь

на самом деле это не обходной путь. sed имеет команду q: (со страницы man):

 q [exit-code]

здесь вы можете определить код выхода, как хотите. например:

совпадающий случай:

kent$  echo "foo"|sed '/foo/ {s/f/b/;q}'                                        
boo

kent$  echo $?
0

Несравненный случай:

kent$  echo "trash"|sed  '/foo/{s/f/b/;q}; /foo/!{q100}'
trash

kent$  echo $?
100

Надеюсь, это ответит на ваш вопрос.

изменить

Я должен добавить, что приведенный выше пример предназначен только для однострочной обработки. Я не знаю вашего точного требования. когда вы хотите получить exit 1. однострочный непревзойденный или весь файл. Если весь файл unmatching case, вы можете рассмотреть awk или даже сделать grep перед обработкой текста...

Ответ 2

Это может сработать для вас (GNU sed):

sed '/search-string/{s//replacement-string/;h};${x;/./{x;q0};x;q1}' file

Если найден search-string, он будет заменен на replacement-string, а в конце файла sed выйдет с кодом возврата 0. Если замена не происходит, код возврата будет 1.

Более подробное объяснение:

В sed пользователь имеет в своем распоряжении два регистра: пространство шаблонов (PS), в которое загружается текущая строка (минус строка), и резервный регистр, называемый пространством удержания (HS), который изначально пуст.

Общая идея состоит в том, чтобы использовать HS в качестве флага, чтобы указать, была ли замена. Если HS еще не заполнен в конце файла, то никаких изменений не было сделано, в противном случае произошли изменения.

Команда /search-string/ соответствует search-string тем, что находится в PS, и если она содержит search-string, выполняются команды между следующими фигурными фигурными скобками.

Во-первых, подстановка s//replacement-string/ (sed использует последнее regexp, т.е. search-string, если сторона lefthand пуста, поэтому s//replacement-string совпадает с s/search-string/replacement-string/), и после этого команда h делает копию PS и помещает его в HS.

Команда sed $ используется для распознавания последней строки файла, а затем происходит следующее.

Сначала команда x заменяет два регистра, поэтому HS становится PS, а PS становится HS.

Затем выполняется поиск PS для любого символа /./ (. означает соответствие любому символу), помните, что HS (теперь PS) изначально был пустым, пока не произошла замена. Если условие истинно, выполняется x, за которым следует команда q0, которая завершает всю обработку sed и устанавливает код возврата на 0. В противном случае выполняется команда x, а код возврата - 1.

N.B. хотя q завершает обработку sed, это не мешает PS повторно собирать sed и печатать как обычно.

Другая альтернатива:

sed '/search-string/!ba;s//replacement-string/;h;:a;$!b;p;x;/./Q;Q1' file

или

sed '/search-string/,${s//replacement-string/;b};$q1' file

Ответ 3

Эти ответы слишком сложны. Что не так, написав немного оболочки script, которая использует grep, чтобы выяснить, есть ли вещь, которую вы хотите заменить, затем использовать sed для ее замены?

grep -q $TARGET_STRING $file
if [ $? -eq 0 ]
then
    echo "$file contains the old site"
    sed -e "s|${TARGET_STRING}|${NEW_STRING}|g" ....
fi

Ответ 4

Мне захотелось усечь файл, уйдя, когда совпадение найдено (и исключить соответствующую строку). Это удобно, когда процесс, который добавляет строки в конце файла, может быть повторно запущен. "Q; Q1" не работал, а просто "Q1" сделал следующее:

если sed -i '/text я хотел найти /Q 1' file.txt тогда  вставить пустую строку в конец файла + новые строки фи вставьте только новые строки без пустой строки

Ответ 5

Ниже приведен шаблон, который мы используем с sed -rn или sed -r.

Вся команда поиска и замены ( "s/.../.../..." ) является необязательной. Если поиск и замена используются для скорости и уже сопоставлены $matchRe, мы используем как можно более быстрое значение $searchRe, используя. где символ не нуждается в повторной проверке и. {$ len} для разделов фиксированной длины шаблона.

Возвращаемое значение для найденного не равно $notFoundExit.

/$matchRe/{s/$searchRe/$replacement/$options; Q}; q$notFoundExit

По следующим причинам:

  • Не тратьте время на тестирование как для согласованного, так и для непревзойденного случая.
  • Не тратится время на копирование в буферы или из них
  • Нет лишних ветвей
  • Разумная гибкость

Изменяя поведение Q-команд, будет изменяться поведение в зависимости от того, когда произойдет выход. Поведение, связанное с применением логической логики к многострочному вводу, требует большей сложности в решении.