在bash中,在sed和cat之后获得了不需要的换行符>>

时间:2017-01-27 13:24:50

标签: linux bash sed scripting hosts

我正在尝试使用我的脚本替换/ etc / hosts文件中的某些行:

#!/bin/bash

hosts_file_path="/etc/hosts"

nas_servers=( 'mynas01' 'mynas02' )

strange_string="<00>"

for nas_name in ${nas_servers[@]}; do
    printf '%ls\n' "$nas_name"
    r="$(nmblookup "$nas_name")"
    if [[ ! -z "$r" ]] && [[ "$r" != "name_query" ]]; then
        l=${#r}
        ls=${#strange_string}
        cl=$(($l-$ls))
        echo "$cl"
        s="${r:0:cl}"
        printf '"%ls"\n' "$s"
        res="$(grep -i "$nas_name" "$hosts_file_path")"
        echo "$res"
        if [ ! -z "$res" ]; then
            sr="s/.*${nas_name}.*//g"
            echo "$sr"
            sed -i "$sr" "$hosts_file_path"
        fi
        printf '%ls\n' "$s" >> "$hosts_file_path"
    fi
done 

搜索例如对于像

这样的行
192.168.1xx.xxx mynas01

并用sed命令将该行(如果已找到)替换为空,但之后添加,例如到

192.169.1xx.xxx mynas01 

我必须这样做(?)这是因为我的LAN网络地址经常变化(确切地说:在每个工作日,但并不总是在工作会话中),因此每次/ etc / hosts文件都不会编辑非常有用,甚至设置像SNMP这样的东西(对于两台服务器)对我来说有点太多开销 - 我只是想把这个脚本放在一个cron作业或rc.local中,以避免smblookups。

现在我的问题:如果我以这种方式制作,在文件结束之后会有更多空的换行符和/或添加的文本之间,我如何避免这种情况,是否有更短的方法呢?

直到现在我得到了结果(/ etc / hosts):

127.0.0.1       localhost
127.0.1.1       hostname.fqdn.example.com    hostnam

(^ the space here got more and more by each call of my script, more newlines and more newlines) 


192.168.1xx.101 mynas01
192.168.1xx.102 mynas02

由于

3 个答案:

答案 0 :(得分:1)

只需使用grep -v从文件中删除您不喜欢的行。比sed之后的grep要容易得多,而且它不会让你留下空白。

答案 1 :(得分:1)

问题是您的sed命令,而不是删除感兴趣的行,将其转换为行,所以实际上你删除旧的NAS条目,同时为其添加新行,这样可以不断添加行。

使用以下sed命令,删除匹配的行:

sr="/${nas_name}/ d"

或更有力地排除误报:

sr="/[[:blank:]]${nas_name}[[:blank:]]*$/ d"

由于使用了双引号字符串,因此您通常必须使用\$作为$字符。 shell应展开。
但是,shell会留下一些不仅仅是语法上有效的变量引用,因此$/按原样传递给sed。 为了更严格地分离shell扩展部分(双引号)和Sed脚本(单引号),您可以使用以下内容,但更难以阅读:sr='/[[:blank:]]'"${nas_name}"'[[:blank:]]*$/ d'。但一般来说,这是一种有价值的方法。

请注意,您的脚本可以通过多种方式进行简化,包括使用单个sed命令直接更新现有条目,而不是先使用sed删除旧条目,然后添加新条目cat

答案 2 :(得分:-1)

假设您有一个看起来像这样的/ etc / hosts文件

192.168.111.000 mynas01
192.168.222.000 mynas01
192.168.333.000 mynas01
000.192.168.000 mynas01

你只需要这样做:

cat /etc/hosts | sed 's/^192\.168\./192\.169\./'

你得到了

192.169.111.000 mynas01
192.169.222.000 mynas01
192.169.333.000 mynas01
000.192.168.000 mynas01