Похоже, вы просто хотите заменить все, что идет после знака равенства, на "0.50"
. Это легко сделать с помощьюawk
:
$ echo 'schedule="0.25"' | awk -F = 'BEGIN { OFS=FS } $1 == "schedule" { $2 = "\"0.50\"" } { print }'
schedule="0.50"
Программа awk
специально ищет запись, чье первое=
-поле с разделителями равно schedule
. Когда он найден, он заменяет второе поле на "0.50"
.
Если 0.50
является переменной, вы можете передать это значение в скрипт awk
следующим образом:
$ newval=0.222
$ echo 'schedule="0.25"' | awk -v nv="$newval" -F = 'BEGIN { OFS=FS } $1 == "schedule" { $2 = sprintf("\"%s\"", nv) } { print }'
schedule="0.222"
И, очевидно, если schedule
также может меняться,
$ newval=0.222
$ variable=schedule
$ echo 'schedule="0.25"' | awk -v v="$variable" -v nv="$newval" -F = 'BEGIN { OFS=FS } $1 == v { $2 = sprintf("\"%s\"", nv) } { print }'
schedule="0.222"
С помощью sed
вы можете просто проигнорировать все, что идет после =
, и заменить его чем угодно:
$ echo 'schedule="0.25"' | sed 's/=.*/="0.50"/'
schedule="0.50"
Чтобы убедиться, что мы заменяем только значение для schedule
, а не значение какого-либо другого параметра,
$ echo 'schedule="0.25"' | sed '/^schedule=/s/=.*/="0.50"/'
schedule="0.50"
Это ставит условие нашей замены; Строка должна иметь строку schedule=
в начале, чтобы она сработала.
Мы могли бы даже вставить переменные оболочки в наше sed
выражение, но имейте в виду, что мы должны убедиться, что значения этих переменных не нарушают синтаксис sed
(, поскольку содержат символы, влияющие на сопоставление или разграничение команд):
$ newval=0.222
$ variable=schedule
$ echo 'schedule="0.25"' | sed "/^$variable=/s/=.*/=\"$newval\"/"
schedule="0.222"
В отличие от примера awk
, здесь мы полагаемся на оболочку для ввода значений наших переменных в sed
сценарий редактирования. Обычно это классифицируется как уязвимость внедрения кода в тех случаях, когда значения переменных не находятся под нашим контролем (, например, когда мы считываем их из предоставленного пользователем источника ).
Usin sed
с нулевым символом в качестве разделителя(-z
):
$ sed -z 's/\([A-Z][a-z]\+\)\n\([A-Z][a-z]\+\)/\1 \2/'
Hello
i
am
John Smith
Использование Raku (, ранее известного как Perl _6)
raku -e 'given lines.join("\n") { S/ $<first>=[<upper><lower>+] \n $<last>=[<upper><lower>+] /$<first> $<last>/.put};'
Пример ввода:
Hello
i
am
John
Smith
goodbye
Пример вывода:
Hello
i
am
John Smith
goodbye
Выше приведено решение, закодированное на Raku, члене семейства языков Perl -. Код подчеркивает несколько преимуществ использования Raku. Вкратце, raku
вызывается в командной строке с флагом -e
, который указывает Raku выполнить следующий -лайнер-код (, а не, например, интерпретировать следующее как сценарий -. файл для открытия/исполнения ).
Данные передаются given
Раку в форме lines
, но по мере того, как подпрограмма Раку lines
auto -жует ввод, данныеjoin
-переводятся с новыми строками. Хотя это может показаться немного запутанным, на самом деле это экономит шаг в конце. Но что более важно, подпрограмма Раку lines
лениво считывает данные, а это означает, что приведенный выше код должен эффективно использовать память -.
Раку реализует S///
"не -деструктивный" оператор, который подобен (, если не идентичен )знакомому s///
оператору (Раку тоже имеет такой ). Оператор Capital-S
имеет одно преимущество, заключающееся в том, что он «оставляет исходную строку нетронутой и возвращает результирующую строку вместо $/ (переменной соответствия )».
При сопоставлении (левой )половины оператора S///
используютсяименованные захваты . Механизм регулярных выражений сначала ищет [<upper><lower>+]
и присваивает его именованному захвату $<first>
, затем ищет\n
(новую строку )и, наконец, ищет другой [<upper><lower>+]
, на этот раз присваивая его именованному захвату. $<last>
. Наконец, в замене (правой )половины оператора S///
два именованных захвата $<first> $<last>
используются для замены левого -совпадения, хотя на a пробел и без новой строки \n
между ними.
Вот и все. Примечание,приведенный выше код будет свернут только что-то вроде George\nHerbert\nWalker\nBush
из 4 строк в 3(George Herbert\nWalker\nBush
).
[Если вы хотите, чтобы все последовательные вхождения [<upper><lower>+]
возвращались в одной строке, пожалуйста, не стесняйтесь публиковать этот вопрос].
https://docs.raku.org/language/regexes#S///_non-destructive_substitution
https://docs.raku.org/language/regexes#index-entry-regex__Named_captures-Named_captures
https://raku.org