更新:感谢每个人的意见。我相信我要实现的目标会有些混乱。我已经在下面的修改中解决了这些问题。
原始问题:
关于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
我试图实现的是,如果以上行存在,则无需对该文件进行任何修改。
希望这有助于澄清所有问题。
答案 0 :(得分:1)
无需阅读while ... done < "$f"
的所有行。您可以改用简单的grep
:
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
答案 1 :(得分:0)
查看您的代码,我有一种感觉,如果您的文件包含“ sip.listen_port”,它将添加额外的一行,但是如果该行不存在,则不会添加。我是对的?如果是这种情况,那么您只需颠倒条件即可:
if [[ ! ("$line" =~ "sip.listen_port*") ]]; then
答案 2 :(得分:0)
如果我正确理解:
$ ll
total 4,0K
-rw------- 1 vkd vkd 0 июл 16 10:03 001565tmp.2rbFa0rT3G
-rw------- 1 vkd vkd 0 июл 16 10:03 001565tmp.6o5BywVcLF
-rw------- 1 vkd vkd 0 июл 16 10:03 805ec0tmp.220Jgcmv0e
-rw------- 1 vkd vkd 0 июл 16 10:03 805ec0tmp.7EGpvDw71e
-rw------- 1 vkd vkd 28 июл 16 10:03 805ec0tmp.F78rxzUBCz
$ cat *
sip.listen_port = something # only file 805ec0tmp.F78rxzUBCz has this entry
脚本:
#!/usr/bin/env bash
FILES_DIR=<your_path>
for filename in `ls $FILES_DIR | grep -E "^(001565|805ec0)"`
do
if grep -q '^sip\.listen_port = something' $filename
then
continue
else
echo "sip.listen_port = something" >> $filename
fi
done
结果:
$ ll
total 20K
-rw------- 1 vkd vkd 28 июл 16 10:03 001565tmp.2rbFa0rT3G
-rw------- 1 vkd vkd 28 июл 16 10:03 001565tmp.6o5BywVcLF
-rw------- 1 vkd vkd 28 июл 16 10:03 805ec0tmp.220Jgcmv0e
-rw------- 1 vkd vkd 28 июл 16 10:03 805ec0tmp.7EGpvDw71e
-rw------- 1 vkd vkd 28 июл 16 10:03 805ec0tmp.F78rxzUBCz
$ cat *
sip.listen_port = something
sip.listen_port = something
sip.listen_port = something
sip.listen_port = something
sip.listen_port = something
P.S:我没有了解UNAME的逻辑...并且您的输出没有解释这个变量是什么,所以我决定它将是“某物”
UPD:
#!/usr/bin/env bash
FILES_DIR="<your_path>"
for filename in `ls $FILES_DIR | grep -E "^(001565|805ec0)"`
do
if grep -qE '^sip.listen_port = [0-9]+' $filename
then
continue
else
uname=`awk '/^account.1.user_name = [0-9]+/ {print $3}' $filename`
echo "sip.listen_port = 9$uname" >> $filename
fi
done
之前:
$ ll
total 16K
-rw------- 1 vkd vkd 26 июл 16 16:36 001565tmp.2rbFa0rT3G
-rw------- 1 vkd vkd 53 июл 16 16:36 001565tmp.6o5BywVcLF
-rw------- 1 vkd vkd 28 июл 16 16:35 805ec0tmp.5ai0gFOkas
-rw------- 1 vkd vkd 25 июл 16 16:35 805ec0tmp.F78rxzUBCz
$ cat 001565tmp.2rbFa0rT3G
account.1.user_name = 105
$ cat 001565tmp.6o5BywVcLF
account.1.user_name = 21516
sip.listen_port = 921516
$ cat 805ec0tmp*
account.1.user_name = 12345
account.1.user_name = 18
之后:
$ cat 001565tmp.*
account.1.user_name = 105
sip.listen_port = 9105
account.1.user_name = 21516
sip.listen_port = 921516
$ cat 805ec0tmp.*
account.1.user_name = 12345
sip.listen_port = 912345
account.1.user_name = 18
sip.listen_port = 918