Найдите шаблон и замените что-нибудь в одной строке после = и "" - PullRequest
4 голосов
/ 06 июля 2019

Я пытаюсь заменить 10.10.10.10 другим IP-адресом, который был передан в качестве аргумента во время выполнения скрипта, поэтому он должен обновить код в моем файле, который содержит следующий код. (Как пример ...)

$cat environment.ts
.....
.........
const WEB_URL = 'http://10.10.10.10';
const API_URL = 'http://20.20.20.20:8080';
.....
............
......
END OF File

Если это только IP-адрес, я могу сразу использовать команду sed, как показано ниже: просто найдите IP: 10.10.10.10 и замените его на некоторый IP, такой как 1.1.1.1

sed -i 's/10.10.10.10/1.1.1.1/g' environment.ts

Но я не могу ретранслировать IP-адрес, поскольку в файле "filename.ts" могут часто обновляться разные IP-адреса.

Поэтому я ищу шаблон "WEB_URL" и пытаюсь заменить новый IP после '=' или после "//". Я попробовал sed и awk и не смог добиться успеха

Ожидаемый результат:

Нужна команда типа sed или awk для замены старого IP-адреса в вышеупомянутом файле "environment.ts", и она должна заменить старый IP-адрес новым IP-адресом. (Как упоминалось выше, старый IP-адрес не является постоянным, он может отличаться, поэтому команда sed или awk, которую я использую, должна искать с шаблоном, например WEB_URL или API_URL, и заменять новый IP рядом с * 1031. * или http//)

С:

.....
const WEB_URL = 'http://<OLD_IP1>';
const API_URL = 'http://<OLD_IP2>:8080';
.....

To:

const WEB_URL = 'http://<NEW_IP1>';
const API_URL = 'http://<NEW_IP2>:8080';

Ответы [ 4 ]

2 голосов
/ 07 июля 2019

Легко сделать с PowerShell:

Add-Type -AssemblyName System.Collections
Add-Type -AssemblyName System.Text.RegularExpressions

[System.Collections.Generic.List[string]]$content = @()

$inputFile   = 'D:\content.txt'
$outputFile  = 'D:\content1.txt'

$regex       = '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'

$newIP1      = '1.1.1.1'
$newIP2      = '1.1.1.2'

foreach($line in [System.IO.File]::ReadLines($inputFile)) {

    if( $line -like '*API_URL*' ) {
        [void]$content.Add( ($line -replace $regex, $newIP2) )
    elseif( $line -like '*WEB_URL*' ) {
        [void]$content.Add( ($line -replace $regex, $newIP1) )            }
    else {
        [void]$content.Add( $line )
    }
}

[System.IO.File]::WriteAllLines( $outputFile, $content ) | Out-Null
2 голосов
/ 07 июля 2019

Используя sed, вот так:

#!/usr/bin/env sh
# POSIX compliant shell script to replace WEB_URL and API_URL
# into environment.ts

NEW_WEB_URL='http://127.0.0.1/'
NEW_API_URL='http://127.0.0.1:8080/'

var_replace_value() {
  # Creates a sed command to replace
  # varname = "something" to varname = "somethingelse"
  # @Params
  # $1: varname
  # $2: newvalue
  [ $# -eq 2 ] || return 1

  _local_varname=''
  _local_newvalue=''

  # Escape parameters to fit a sed command
  _local_varname="$(echo "${1}" | \
    sed \
      --posix \
      --regexp-extended 's/([\\\/\(\)\{\}\[\$\^]|\])/\\\1/g')"
  _local_newvalue="$(echo "${2}" | \
    sed \
      --posix \
      --regexp-extended 's/([\\\/\(\)\{\}\[\$\^]|\])/\\\1/g')"

  env printf "s/(%s[[:space:]]*=[[:space:]]*['\"])[^'\"]+/\\\\1%s/g" \
    "${_local_varname}" \
    "${_local_newvalue}"
}

# Build the sed script to replace the URLs
WEB_URL_REPLACE_CMD="$(var_replace_value 'WEB_URL' "${NEW_WEB_URL}")"
API_URL_REPLACE_CMD="$(var_replace_value 'API_URL' "${NEW_API_URL}")"
URL_REPLACE_SED_CMDS="${WEB_URL_REPLACE_CMD};${API_URL_REPLACE_CMD}"

sed \
--posix \
--in-place='.bak' \
--regexp-extended "${URL_REPLACE_SED_CMDS}" environment.ts
2 голосов
/ 07 июля 2019

Форма sed, которая находит вхождение и затем использует альтернативные разделители, чтобы избежать экранирования '/' символов, можно записать:

sed '/locate/s#find#replace#'

Но так как вы хотите иметь возможность передавать IP как переменную, вам нужно заключить выражение в двойные кавычки, чтобы произошло расширение переменной, и мы захотим использовать квантификаторы {x,y}, поэтому нам понадобится -r опция, позволяющая включить расширенное сопоставление регулярных выражений , в результате чего появится форма

sed -r "/locate/s#find#replace#"

В вашем случае, учитывая IP-адрес, указанный в переменной ip, и ваше желание найти либо WEB_URL, либо API_URL (за которым следует пробел и знак '='), а затем только заменить IP-адрес на тот, который содержится в $ip, вы можете использовать:

sed -r "/(WEB|API)_URL\s=/s#[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}#$ip#"

Где твой

  • locate is /(WEB|API)_URL\s=/
  • найти для IP - [0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}
  • заменить is $ip

Пример входного файла

Файл примера показывает OTH_URL и API_URL (без пробелов и '='), которые остаются нетронутыми:

$ cat environment.ts
const OTH_URL = 'http://10.10.10.10';
const WEB_URL = 'http://10.10.10.10';
const API_URL = 'http://20.20.20.20:8080';
const API_URL (can either be 'http://10.10.10.10' or 'http://10.10.10.10:8080')

Запуск выражения sed в приведенном выше файле примера приведет к:

$ ip=12.12.12.12
$ sed -r "/(WEB|API)_URL\s=/s#[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}#$ip#" \
environment.ts
const OTH_URL = 'http://10.10.10.10';
const WEB_URL = 'http://12.12.12.12';
const API_URL = 'http://12.12.12.12:8080';
const API_URL (can either be 'http://10.10.10.10' or 'http://10.10.10.10:8080')

Где ни строка OTH_URL, ни строка, в которой за API_URL не следует пробел и '=' не остаются неизменными.

Вам нужно будет сделать отдельные звонки, чтобы изменить WEB_URL и API_URL на разные IP-адреса, если это необходимо. Это можно сделать с помощью отдельных sed выражений -e, например:

$ ip1=12.12.12.12
$ ip2=14.14.14.14
$ sed -r -e "/WEB_URL\s=/s#[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}#$ip1#" \
         -e "/API_URL\s=/s#[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}#$ip2#" \
         environment.ts
const OTH_URL = 'http://10.10.10.10';
const WEB_URL = 'http://12.12.12.12';
const API_URL = 'http://14.14.14.14:8080';
const API_URL (can either be 'http://10.10.10.10' or 'http://10.10.10.10:8080')

Посмотрите вещи и дайте мне знать, если у вас есть вопросы.

2 голосов
/ 07 июля 2019

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

$filetoworkon = 'environment.ts'
$old = '10.10.10.10'
$new = '7.7.7.7'

Get-Content $filetoworkon |
    ForEach-Object {
        $_ -replace [regex]::Escape($old), $new
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...