2014-10-27 109 views
0

我需要创建一个脚本,它将在文件(XML)中的特定行之后添加文本。这是我到目前为止:将文本添加到特定的行linux脚本

echo 
echo "This script will blah blah blah" 
echo 
read -p "Press Enter to continue..." 
clear 

var1=`grep -n "<string>" <file> | awk -F ":" '{print $1}'` //var1 = line number 

function EnterID() 
{ 
echo -n "Enter ID: " 
read ID 
var2="text to be added" 
sed "$((var1+1))i$var2" <file> > <file> //add text to file, overwrite file 
#var1="$((var1+1))" //increment line number??? 
echo 
echo "ID successfully added to file" 
echo 
EnterNewID 
} 

EnterNewID() 
{ 
read -p "Press Enter to continue..." 
clear 
echo -n "Would you like to add another ID? (y)es or (n)o: " 
read answer 
clear 

if [ $answer = "y" ]; then 
    EnterID 
else 
    exit 
fi 
} 

EnterID 

该脚本第一次工作。但是,如果用户尝试添加附加ID,则第一个ID将被覆盖。我也应该说我不是程序员(更多的是网络人员)。我有一点经验脚本,但仅此而已。

其它信息:

原件:

<SubscriberXML> 
    <Subscribers> 
    <Subscriber address="0.0.0.0" id="1" /> 
    <Subscriber address="0.0.0.0" id="2" /> 
    <Subscriber address="0.0.0.0" id="3" /> 
    <Subscriber address="0.0.0.0" id="4" /> 
    <Subscriber address="0.0.0.0" id="5" /> 
    </Subscribers> 
</SubscriberXML> 

初次使用后:

第二使用
<SubscriberXML> 
    <Subscribers> 
    <Subscriber address="0.0.0.0" id="X" /> // newly added ID 
    <Subscriber address="0.0.0.0" id="1" /> 
    <Subscriber address="0.0.0.0" id="2" /> 
    <Subscriber address="0.0.0.0" id="3" /> 
    <Subscriber address="0.0.0.0" id="4" /> 
    <Subscriber address="0.0.0.0" id="5" /> 
    </Subscribers> 
</SubscriberXML> 

后:

<SubscriberXML> 
    <Subscribers> 
    <Subscriber address="0.0.0.0" id="Y" /> // newly added ID 
    <Subscriber address="0.0.0.0" id="1" /> 
    <Subscriber address="0.0.0.0" id="2" /> 
    <Subscriber address="0.0.0.0" id="3" /> 
    <Subscriber address="0.0.0.0" id="4" /> 
    <Subscriber address="0.0.0.0" id="5" /> 
    </Subscribers> 
</SubscriberXML> 

想要:

<SubscriberXML> 
    <Subscribers> 
    <Subscriber address="0.0.0.0" id="Y" /> 
    <Subscriber address="0.0.0.0" id="X" /> 
    <Subscriber address="0.0.0.0" id="1" /> 
    <Subscriber address="0.0.0.0" id="2" /> 
    <Subscriber address="0.0.0.0" id="3" /> 
    <Subscriber address="0.0.0.0" id="4" /> 
    <Subscriber address="0.0.0.0" id="5" /> 
    </Subscribers> 
</SubscriberXML> 
+0

嗨,你能提供一个你想覆盖的文件的例子,以及预期的结果吗?这将有所帮助。 – Matt 2014-10-27 16:14:24

+0

当然有一点 – dej27 2014-10-27 16:33:06

+0

我建议你在这里使用一些xml处理工具,而不是sed和awk的combinator。你见过xmlstarlet工具吗? https://stackoverflow.com/questions/5591414 – marbu 2014-10-27 16:59:50

回答

0

你不能做到这一点:

any_command file > file 

外壳将处理重定向第一,该文件将被截断之前启动命令。您现在将一个空文件传递给该命令。

有几个技巧:

  1. 使用临时文件并覆盖原来的文件,如果命令成功

    temp=$(mktemp) 
    any_command file > "$temp" && mv "$temp" file 
    
  2. 完成安装moreutils包,并使用sponge命令

    any_command file | sponge file 
    
+0

你是对的,当我尝试做文件>文件时,我留下了一个空白文件。但是,在测试过程中,我使用了file> testfile,它在第一次使用后确实输出了正确的输出。无论如何,我的问题依然存在。 – dej27 2014-10-27 17:31:00

+0

如果您从不将“testfile”写回“file”,则sed命令永远不会看到更新的文件。 – 2014-10-27 17:34:40

+0

谢谢格伦。我得到它使用命令文件>“$ temp”&& mv“$ temp”文件。就像你说的那样,它只是没有使用更新的文件。 – dej27 2014-10-27 17:46:12

0

如果你只是收集所有的补充,然后做了一个替换,程序和问题会简单得多。

nl=' 
' 
replace="i\\$nl" 
while read -p "What should be added? (Empty input to finish) " entry; do 
    if [ "$entry" = "" ]; then 
     break 
    fi 
    replace="$replace$nl$entry" 
done 
sed -i "/<string>/$replace" file