Как найти ip в строке и заменить его скриптом bash? - PullRequest
0 голосов
/ 27 января 2019

У меня есть такой файл

www       IN       A       192.168.10.1
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3

Я хочу написать bash-скрипт, который получает 3 ввода, как это

./script.sh network.com www 192.168.10.10

и скрипт

project=$1
server=$2
ip=$3
h=$(awk -F "$server       IN       A" '{print $2}' /home/forward.$project)
sed -i "s/$h/$ip/"

Я хочу найти строку, которая начинается со второго ввода и заменить (ip) на третий, но мой сценарий не работает.

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Использование awk:

$ echo network.com www 192.168.10.10 | 
awk '
NR==FNR {
    a=$2   # store hostname
    b=$3   # and ip
    next   # .
}
$1==a {    # if hostname matches
    sub(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/,b)  # replace ip looking string
}1' - a_file                                                 # output

Выход:

www       IN       A       192.168.10.10
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3

Редактировать

Версия, которая добавляет несоответствующую запись в конец:

$ echo network.com www2 192.168.10.10 |
awk '
NR==FNR {
    a=$2           # store hostname
    b=$3           # and ip
    next           # not needed for this input but good practise
} 
FNR==1 { t=$0 }    # store a template record for later use
$1==a {            # if hostname matches
    sub(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/,b)  # replace ip looking string
    f=1            # flag up when there was replace
}
1;                 # output
END {              # in the end 
    if(!f) {       # if there was no replace
        sub(/^[^ \t]+/,a,t)  # replace the template
        sub(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/,b,t)
    print t        # and output it
    }
}' - a_file

Выход:

www       IN       A       192.168.10.1
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3
www2       IN       A       192.168.10.10
0 голосов
/ 27 января 2019
$ cat script.sh
#!/bin/env bash
project=$1
server=$2
ip=$3
file="file"     # change to "/home/forward.$project"

awk -v server="$server" -v ip="$ip" '
    $1 == server {
        sub(/[^[:space:]]+[[:space:]]*$/,"")
        $0 = $0 ip
        found = 1
    }
    { print; lastLine=$0 }
    END {
        if ( !found ) {
            match(lastLine,/^[^[:space:]]+[[:space:]]+/)
            gsub(/^[^[:space:]]+[[:space:]]+|[^[:space:]]+[[:space:]]*$/,"",lastLine)
            printf "%-*s %s%s\n", RLENGTH-1, server, lastLine, ip
        }
    }
' "$file"

.

$ ./script.sh network.com www 192.168.10.10
www       IN       A       192.168.10.10
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3

$ ./script.sh network.com fluffy 192.168.10.10
www       IN       A       192.168.10.1
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3
fluffy    IN       A       192.168.10.10

$ ./script.sh network.com super_long_server 192.168.10.10
www       IN       A       192.168.10.1
webmail   IN       A       192.168.10.2
mail      IN       A       192.168.10.3
super_long_server IN       A       192.168.10.10

Вышеуказанное будет работать переносимо и надежно (т. Е. Нет вероятности ложных совпадений или других сбоев из-за частичного совпадения или символов регулярного выражения или разделителей, таких как /, которые появляются во входных данныхили аргументы) использование любого awk в любой оболочке на любой машине UNIX

Чтобы записать обратно в исходный файл, вы можете добавить -i inplace в начало сценария awk, если вы используете GNU awk, или добавить > tmp && mv tmp "$file" после окончания в противном случае.

0 голосов
/ 27 января 2019

Вы можете выбрать строку в sed и выполнить замену регулярного выражения.

project=$1
server=${2//./\\.}  # escape '.' to avoid problems with sed if $server contains some
ip=$3
sed  -E "/^$server /s/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/$ip/" "$1"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...