Linux 在bash中,sed和cat>&燃气轮机;
我试图用我的脚本替换/etc/hosts文件中的一些行:Linux 在bash中,sed和cat>&燃气轮机;,linux,bash,sed,scripting,hosts,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 [[
#!/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
并使用sed命令将该行(如果找到)替换为nothing,但随后添加,例如
192.169.1xx.xxx mynas01
我不得不这么做(?)因为我的LAN网络地址经常变化(确切地说:在每个工作日,但不总是在工作会话中),所以每次编辑/etc/hosts文件都不是很有用,即使是设置SNMP之类的东西(对于两台服务器)对我来说有点太多的开销-我只想把这个脚本放在cron作业或rc.local中,以避免SMB查找
现在我的问题是:如果我这样做,在文件结束后和/或在添加的文本之间会有更多的空换行符,我如何避免这种情况,有没有更短的方法
到目前为止,我得到的结果是(/etc/hosts):
谢谢只需使用
grep-v
从文件中删除您不喜欢的行即可。它比现在的grep
之后的sed
容易得多,而且不会留下空白行。假设您有一个类似于这样的/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
问题是,您的
sed
命令没有删除感兴趣的行,而是将其变为一个空行,因此实际上,您在为其添加新行时会清空一个旧的NAS条目,这会不断添加行
改用以下sed
命令删除匹配行:
sr="/${nas_name}/ d"
或者,更确切地说,为了排除误报:
sr="/[[:blank:]]${nas_name}[[:blank:]]*$/ d"
由于使用了双引号字符串,因此通常必须对$
字符使用\$
。外壳不应膨胀。但是,shell只留下一些语法上无效的变量引用,因此
$/
按原样传递给sed
。为了更严格地分离shell扩展部分(双引号)和Sed脚本(单引号),您可以使用以下内容,但是这更难理解:
sr='/[[:blank:]'“${nas_name}”[[:blank:]*$/d'
。不过,总的来说,这是一种值得采用的方法
请注意,可以通过多种方式简化脚本,包括使用单个
sed
命令直接更新现有条目,而不是首先使用sed
删除旧条目,然后使用cat
添加新条目,但grep-v返回一个grep匹配的反向搜索。如何对两个或多个字符串(mynas01、mynas02、mynas03…)执行此操作?grep-v
可能稍微容易一些,但如果您还希望就地更新输入文件(如此处所示),sed-I
非常方便,OP唯一的问题是使用s
函数将匹配行替换为空字符串,而不是使用d
函数将其删除。@程序员:egrep-v'mynas[0-9]+'
是一种方法。正如您所看到的,有一个字符串列表(或者更好:我想更改的nas的名称列表:mynas01,…)原始的/etc/hosts文件是什么样子的?不清楚您的答案与问题的关系。问题是为什么每次运行后文件中都会出现新的空行,以及如何避免它们。(有效地)更新条目的部分已经可以很好地工作了——尽管它比需要的更麻烦(先删除旧条目,然后附加更新版本)。虽然如你所建议的那样使用直接替换是更好的,但你没有抓住问题的关键。
sr="/${nas_name}/ d"
sr="/[[:blank:]]${nas_name}[[:blank:]]*$/ d"