简体   繁体   English

在bash shell中有条件地查找/替换

[英]Conditional find / replace in bash shell

My issue should be rather simple, and I'm guessing where I'm failing is syntax related. 我的问题应该很简单,我猜我失败的地方与语法有关。 I'm looking to write a simple shell script which manipulates an XML file in the following way. 我正在寻找一个简单的shell脚本,该脚本以以下方式操作XML文件。

The data points inside each tag will be numeric values. 每个标签内的数据点将是数字值。 These should all be positive, so if there exists a negative value inside any tag within the XML file, I would like to replace it with a zero. 这些都应该是正数,因此,如果XML文件中的任何标记内都存在负值,我想将其替换为零。 For example, the following XML file - call it "file.xml" 例如,以下XML文件-称为“ file.xml”

<tag1>19</tag1>
<tag2>2</tag2>
<tag3>-12</tag3>
<tag4>37</tag4>
<tag5>-41</tag5>

should be replaced with 应该替换为

<tag1>19</tag1>
<tag2>2</tag2>
<tag3>0</tag3>
<tag4>37</tag4>
<tag5>0</tag5>     

My thinking on this would be if I grepped any instance of the string ">-*<" in the file and used sed to replace it with >0< as follows. 我的想法是,如果我在文件中添加了字符串“>-* <”的任何实例,并使用sed将其替换为> 0 <,如下所示。

#!/bin/bash
STRING=">-*<"
if grep -xq "$STRING" file.xml
then
sed -i 's/$STRING/>0</g' file.xml
else
echo "that string was not found in the file"
fi

However all I'm getting in return is the echo string "that string was not found in the file" being returned, even tho I have included negative values in the file. 但是,我得到的只是返回的回显字符串“在文件中找不到该字符串”,即使我在文件中包含了负值。 Does the * not take into account any string following the minus sign in this example? 在此示例中,*是否不考虑减号后面的任何字符串? Naturally there can be any number following the minus sign, so i'm thinking my problem is how I've defined the variable: STRING=">-*<".... Any pointers in the right direction would be greatly appreciated. 当然,减号后可以有任何数字,所以我在想我的问题是如何定义变量:STRING =“>-* <” ....朝正确方向的任何指针将不胜感激。 Thanks in advance. 提前致谢。

Try this: 尝试这个:

STRING=">-.*<"

or better yet: 或更好:

STRING=">-[0-9]*<"

In general, the * means 'any number of the last character/class of characters', so .* matches any string, [0-9]* any string consisting only of digits. 通常,*表示“最后一个字符/字符类的任何数目”,因此。*匹配任何字符串,[0-9] *匹配仅由数字组成的任何字符串。 Your expression would have matched '><', '>-<', '>--<', '>---<' and so on. 您的表达式将与'> <','>-<','>-<','> --- <'等匹配。

cat aaa.txt
<tag1>19</tag1>
<tag2>2</tag2>
<tag3>-12</tag3>
<tag4>37</tag4>
<tag5>-41</tag5>

replace negatives with zero and write to a new file 将负数替换为零并写入新文件

sed 's/-[0-9][0-9]*/0/' aaa.txt > a2.txt

check the new file 检查新文件

cat a2.txt
<tag1>19</tag1>
<tag2>2</tag2>
<tag3>0</tag3>
<tag4>37</tag4>
<tag5>0</tag5>
>-[0-9]+<

是一个或多个字符,是更好的选择

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM