首页 > 解决方案 > 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

我试图实现的是,如果存在上述行,则不应对文件进行任何修改。

希望这有助于澄清任何问题。

标签: bashshell

解决方案


无需阅读所有带有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

推荐阅读