简体   繁体   English

如何在一行中找到ip并将其替换为bash脚本?

[英]How find ip in a line and replace it with bash script?

I have a file like this 我有一个这样的文件

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

I want to write a bash script that get 3 input like this 我想写一个bash脚本,得到这样的3个输入

./script.sh network.com www 192.168.10.10

and script is 和脚本是

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

I want to find line that start with second input and replace (ip) with third input but my script doesn't work. 我想找到以第二个输入开头的行,并用第三个输入替换(ip),但是我的脚本不起作用。

You can select the line in sed and do regexp replace. 您可以选择sed中的行并进行regexp替换。

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"

Using awk: 使用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

Output: 输出:

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

Edit : 编辑

A version which adds non-matching record to the end: 一个在末尾添加不匹配记录的版本:

$ 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

Output: 输出:

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
$ 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

The above will work portably and robustly (ie no chance of false matches or other failures due to partial matching or regexp characters or delimiters like / appearing in the input or arguments) using any awk in any shell on any UNIX box 上面的代码可以在任何UNIX盒子上的任何shell中使用任何awk进行移植,并且功能强大(例如,由于部分匹配或regexp字符或定界符(例如/出现在输入或参数中)而不会导致错误匹配或其他失败)

To write back to the original file you could add -i inplace at the front of the awk script if you're using GNU awk, or add > tmp && mv tmp "$file" after the end of it otherwise. 要写回原始文件,如果使用的是GNU awk,则可以在awk脚本的开头添加-i inplace ,否则可以在末尾添加> tmp && mv tmp "$file"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM