Код возврата sed для бездействия
Я использую sed
для обновления моего конфигурационного файла json во время выполнения.
Иногда, когда шаблон не соответствует в json файле, все еще sed
завершается с кодом возврата 0.
Возврат 0 означает успешное завершение, но почему sed
возвращает 0, если он не находит правильный шаблон и не обновляет файл? Есть ли обходной путь для этого?
Спасибо!
Ответы
Ответ 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-команд, будет изменяться поведение в зависимости от того, когда произойдет выход. Поведение, связанное с применением логической логики к многострочному вводу, требует большей сложности в решении.