sed или awk с переменными и специальными символами - PullRequest
1 голос
/ 30 апреля 2020

Я хочу использовать awk или sed для замены 1 строки в моем файле:

содержимое моего файла:

server.modules += ( "mod_redirect" )

$SERVER["socket"] == ":8080" {
    $HTTP["host"] =~ "(.*)" {
        url.redirect = ( "^/(.*)" => "https://someurl.com/unauthorised" )
    }
}

Я хочу изменить строку, содержащую url.redirect Новый строка находится в переменной и содержит специальный символ, который будет выглядеть примерно так url.redirect = ( "^/(.*)" => "http://newurl.com/newpath" )

, поэтому я использовал следующую команду sed:

sed "/url\.redirect =/s/.*/$newline/" 10-redirect.conf

Но я получил ошибку, связанную со специальными символами внутри переменная newline.

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

Как использовать переменные со специальными символами в sed или awk?

Ответы [ 3 ]

3 голосов
/ 30 апреля 2020

С помощью команды GNU sed и c (которая заменяет совпавшие строки предоставленной строкой). Если в начале строки есть пробелы, используйте префикс \ для их сохранения

sed '/url\.redirect =/c\'"$newline"

Однако команда c по-прежнему разрешает escape-последовательности, например:

$ s='   rat\tdog\nwolf'
$ seq 3 | sed '2c\'"$s"
1
   rat  dog
wolf
3


Чтобы добавить содержимое буквально и надежно, используйте команду r

echo "$newline" | sed -e '/url\.redirect =/ {r /dev/stdin' -e 'd}'

Вот команда r в действии

$ s='   rat\tdog\nwolf'
$ echo "$s" | sed -e '2 {r /dev/stdin' -e 'd}' <(seq 3)
1
   rat\tdog\nwolf
3
1 голос
/ 30 апреля 2020

Не могли бы вы попробовать следующее. Это должно поставить те же пробелы перед новым значением, что было раньше.

newline='url.redirect = ( "^/(.*)" => "https://example.com/authorised" )'
awk -v line="$newline" '
/url.redirect =/{
  match($0,/^ +/)
  print substr($0,RSTART,RLENGTH) line
  next
}
1
'  Input_file
1 голос
/ 30 апреля 2020

Вы получаете сообщение об ошибке в sed, так как он использует регулярное выражение, а ваша замещающая строка может содержать метасимволы, такие как & или / (разделители) и c.

Это awk будет безопаснее использовать из-за подхода без регулярных выражений:

newline='url.redirect = ( "^/(.*)" => "https://example.com/authorised" )'

awk -i inplace -v line="$newline" 'index($0, "url.redirect =") {
   sub(/[^[:blank:]].*/, "")
   $0 = $0 line
} 1' file

server.modules += ( "mod_redirect" )

$SERVER["socket"] == ":8080" {
    $HTTP["host"] =~ "(.*)" {
    url.redirect = ( "^/(.*)" => "https://example.com/authorised" )
    }
}

Обратите внимание, что использование ENVIRON позволит всем специальным символам оболочки awk:

export newline

awk -i inplace 'index($0, "url.redirect =") {
   sub(/[^[:blank:]].*/, "")
   $0 = $0 ENVIRON["newline"]
} 1' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...