Используя sed со специальными символами

Это хитро. Во-первых, только из предосторожности, помещает вызов в функцию в начале сценария и не называют его до конца:

% killmenow() { ... }
...
% killmenow
EOF

Это - лучший способ быть уверенным, что все из текущего сценария было полностью считано и скопировано в память. Просто высказывание.

Теперь для моей попытки ответа...

POSIX указывает jobs утилиты для этих видов вещей. А именно, комбинация wait, trap, и kill было бы самым безопасным, я думаю. Для получения вещей, проходящих максимально чисто, можно использовать newgrp также, который является в точности как exec в качествах наследования за исключением, как могло быть основным в этом случае, process id.

Хорошо, таким образом, я знаю, что это походит на много, но это не так для взгляда на, в конце концов:

% suicide() { _me="${1}" ; ( 
>> trap 'wait "${_me}" && set -- &&\
>>> eval `newgrp && exec { YOUR | CMD | HERE }`' INT &&\
>> kill -s INT "-${_me}"
>> ) & }
...
% suicide "${$}"

Хорошо, таким образом, вот рабочий процесс:

  • Сначала мы загружаем и запускаем весь скрипт, и мы уверены в этом, потому что мы не делаем suicide до самой последней строки.
  • Мы передаем suicide копия нашего process id затем сохраните его к $_me, который мы могли столь же легко получить из suicide также в этом случае, но мы могли бы использовать его в другом месте, кто знает.
  • Из подоболочки мы звоним trap просканировать в trapped '$cmd' и дайте этому команду быть в поисках любого слуха INT звонить.
  • Уверенный все готово, наш вызов к kill наше самое последнее; kill проблемы INTERRUPT SIGNAL не только к $_me но мы - укажите это $_my целая группа процесса должна получить его. Не бойтесь - если Ваша целая система не уже безумна - $_me ничего не может уничтожить $_me не должен мочь прямо сейчас так или иначе. Кроме того, Вы не имеете к - укажите это в kill PID аргумент также; я просто пытаюсь быть полным.

Хорошо, но мы не сделаны, правильно? Нет, мы помещаем целый набор команд в a & фоновая подоболочка так trap все еще бродит вокруг и может поймать наш INT звонить.

  • Получив INT, trap ТЕПЕРЬ оценивает 'quoted argument' - важно помнить, что что-либо в этой строке только теперь вытаскивается.
  • На всякий случай $_me имеет несколько других свободных концов для связывания в другом месте, trap первые вызовы wait на $_me который будет оставаться на линии только столько, сколько она должна.
  • Когда готовый, мы вычищаем любого остающегося env $vars с set -- и затем мы приступаем к делу.

newgrp разработан, чтобы быть выполненным в interactive shell - который, как не обязательно предполагают, предоставлял процессу такой чистый Escape как это. На самом деле, если Ваша система group потребуйте паролей - который они не были должны - это не работать на Вас и умрут теперь.

Я называю этот метод подлым ниже, но я выпрямил его из ИНСТРУКЦИЙ POSIX:

Общая реализация newgrp это текущее использование оболочки exec накладывать себя с newgrp, который в свою очередь накладывает себя с новой оболочкой после изменяющейся группы...

Затем в следующем абзаце...

Команда newgrp предназначается только для использования от интерактивного терминала. Это не предлагает полезный интерфейс для поддержки приложений.

Таким образом, подлая часть eval, который может быть довольно хорош в такой вещи - как сохранение и многократное использование "$@" например, но другое время, возможно...

  • Вместо этого мы косвенно eval a newgrp && exec оператор, что первые загрузки другой процесс, который, как только предполагается, принимает его следующее управление от интерактивной подсказки, затем мы украдкой exec в черном ходе содержание { YOUR | CMD }.

К этому времени мы должны запускать новый скрипт в новой оболочке в новой группе процесса в чистой среде после необходимости ожидать только, пока было на самом деле необходимо и осуществить все это довольно полностью.

На самом деле мы были так полны, что мы могли безопасно сделать это:

...exec { wget -O - "${URL}" >"${0}" ; exec "${0}" }

2
18.06.2014, 15:47
5 ответов

Попробуйте это,

$ sed 's~<offset xmlns="">1~<offset xmlns="">99~g' file
          <offset xmlns="">99</offset>

Используйте другой разделитель седа, если вход содержит косые черты.

4
27.01.2020, 21:49

Не нужно использовать / в sed, можно использовать запятую, например:

sed -i 's,<offset xmlns="">1</offset>,NEW_TEXT,' FILE
7
27.01.2020, 21:49

Обычно все это не нужно в самой функции s/ search/replace/, а можно сначала /адрес/, а затем условно /s///. Это может не только помочь с удобочитаемостью, но и, чтобы избежать некоторых проблем, о которых вы упоминаете, может быть увеличена производительность:

sed '/offset xmlns=/s/>1</>99</'
2
27.01.2020, 21:49

Используйте правильный парсер для XML-файлов. Например, я бы использовал xsh и использовал следующий скрипт:

for my $file in { @ARGV } {
    open $file ;
    for //offset set . 1 ;
    save :b ;
}
1
27.01.2020, 21:49

Я бы заменил 17-й символ строки, который содержит значение:

sed -i 's/^\(.\{17\}\)./\1VALUE/' file.xml

Заменить VALUE на новое значение для . Eg.

sed -i 's/^\(.\{17\}\)./\18/' file.xml

чтобы изменить его на 8.

.
0
27.01.2020, 21:49

Теги

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