bash - Shell 脚本 - 如果某些文本不存在,则读取文件并添加行
问题描述
更新:感谢大家的意见。我相信我想要实现的目标有点混乱。我已经在下面的编辑中解决了这些问题。
原始问题:
当谈到 shell 脚本时,我是一个菜鸟,并尽力想出我自己的。以下代码经过多次迭代才达到这一点。
很抱歉,如果我已经回答了这个问题,我无法让它满足我的需要,因此是这个问题的原因。
场景:IP 电话配置服务器。一个文件夹包含多个,其中大多数是 .cfg 文件。其中,如果文件名以 001565 或 805ec0 开头,则添加带有“sip.listen_port”的行。忽略其他一切。
问题:我可以在没有任何问题的情况下完成上述操作。但是缺点是如果文件已经有这一行,我的脚本会添加另一行。
预期结果:我想做的是,阅读文件,查看文本是否存在,然后才添加该行。这是我失败的地方。
任何帮助我指出正确方向的帮助将不胜感激。
当前代码:
#!/bin/bash
#check old yealink phones are there
if ls 001565* 1> /dev/null 2>&1; then
LOOP=0
FILES=001565*
else
LOOP=1
FILES=805ec0*
fi
while [ $LOOP -lt 2 ]; do
for f in $FILES
do
while read -r line; do
if [[ "$line" =~ "sip.listen_port*" ]]; then
UNAME=$(awk '/user_name/{print $NF}' "$f")
# take action on each file. $f store current file name
# check the lenght of extension number and set the
if [ ${#UNAME} -lt 2 ]; then
echo "sip.listen_port = 900$UNAME" >> $f
elif [ ${#UNAME} -lt 3 ]; then
echo "sip.listen_port = 90$UNAME" >> $f
elif [ ${#UNAME} -lt 4 ]; then
echo "sip.listen_port = 9$UNAME" >> $f
else
UNAME=${UNAME:(-3)}
echo "sip.listen_port = 9$UNAME" >> $f
fi
fi
done < "$f"
done
#check new yealink phones are there
if ls 805ec0* 1> /dev/null 2>&1; then
FILES=805ec0*
LOOP=$((LOOP+1))
else
LOOP=$((LOOP+2))
fi
done
编辑1: 为了消除混淆,让我添加一张图片,展示典型文件夹中的文件以及典型文件的内容。
典型文件内容:
#!version:1.0.0.1
## the file header "#!version:1.0.0.1" can not be edited or deleted. ##
account.1.auth_name = 105
account.1.display_name = 105
account.1.enable = 1
account.1.label = 105
account.1.password =
account.1.sip_server.1.address = pbx.dns.name
account.1.sip_server.2.address =
account.1.user_name = 105
auto_provision.server.url = http://provisioning.url/
工作原理:脚本将检查当前文件夹中以 001565 或 805ec0 开头的每个文件并添加以下行。
sip.listen_port = 9XXX
我试图实现的是,如果存在上述行,则不应对文件进行任何修改。
希望这有助于澄清任何问题。
解决方案
无需阅读所有带有while ... done < "$f"
. 您可以使用 simplegrep
代替:
for ...
if ! grep -q '^[[:blank:]]*sip\.listen_port' "$f"; then
...
...
echo "sip.listen_port = something" >> "$f"
fi
done
如果你坚持使用while
,你可以试试这个:
for ...
found=0
while IFS= read -r line; do
[[ $line =~ ^[[:blank:]]*"sip.listen_port" ]] && { found=1; break;}
done < "$f"
if ! ((found)); then
...
...
echo "sip.listen_port = something" >> "$f"
fi
done
推荐阅读
- android - 请求权限
- mysql - 转置部分 SQL 结果以合并记录
- c# - Hortonworks webhdfs 我尝试使用 curl 命令列出它将在 Hortonworks 控制台上工作的所有文件夹,但不能在 C# 中使用
- ios - Unity iOS 背景音频变得静音
- c++ - c++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 的类型/值不匹配
- javascript - TypeError:无法读取未定义的属性“价格”
- php - 为每个用户将信息提取到 xml 文件中
- reactjs - React - 在组件之间共享数据的最有效方式
- c# - MediaElement.NaturalDuration.TimeSpan 返回错误值
- javascript - 导入/导出声明只能出现在模块的顶层