Solaris,版本: 11.10.0,REV=2005.01.21.15.53
我有一个文件test.txt,它包含如下所示的值:
<Info>
<AccountNumber>23456789</AccountNumber>
<BranchNumber>004</BranchNumber>
<TransitNumber>01646</TransitNumber>
<NameAndCity>XYZ Bank</NameAndCity>
<OwnerFullName>ABC XYZ</OwnerFullName>
</Info>所有的信息都在一条线上,我们有像上面这样的多行,其他标签也是可用的。
它还包含其他标记值。另外,如果标记值包含"333“组合,我不想替换它们。
我想使用sed命令将标记的值替换为33333,替换后,我希望将更新后的信息保存到同一个文件中。
产出应是:
<Info>
<AccountNumber>33333333</AccountNumber>
<BranchNumber>33333</BranchNumber>
<TransitNumber>3333333</TransitNumber>
<NameAndCity>333 33333</NameAndCity>
<OwnerFullName>3333 33333</OwnerFullName>
</Info>我对shell脚本很陌生,不完全能够编写与之匹配的模式。
到目前为止,我已经实现了前两个标记值,但它不起作用:
sed 's/(<AccountNumber>)\+[0-2,4-9]*$/\1 33333333/' test.txt
sed 's/(<BranchNumber>)\+[0-2,4-9]*$/\1 33333/' test.txt任何帮助都将不胜感激。
发布于 2019-01-26 13:52:31
试试这个:
sed -e '/333/!{' -e 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}'例:
$ sed -e '/333/!{' -e 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}' test.txt
<Info>
<AccountNumber>333333333</AccountNumber>
<BranchNumber>33333</BranchNumber>
<TransitNumber>01646</TransitNumber>
<NameAndCity>XYZ Bank</NameAndCity>
<OwnerFullName>ABC XYZ</OwnerFullName>
</Info>一种非常简单的方法,如果您想测试ok并想要改变文件的位置,添加-i开关。
我没有Solaris测试,所以不能确定。
试试这个简单的perl,看看它是否有效:
perl -pe 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#' test.txt如果它有效的话,我们可以添加其他的。
因此,对于你的逻辑首先写在问题中,应该是这样的:
perl -pe 'unless (/333/) {s#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}' test.txt你可以自己添加其他的副词。#将取代通常的/ of s,这是一种更简单的方法,可以避免在封闭标记(即s#from#to#;)中转义/。
这是相当简单的,所以我认为你不会有困难:)
将-i开关添加到内部更改,如:perl -i -pe '...。
发布于 2019-01-26 14:37:45
$ cat file.txt
<Info>
<AccountNumber>23456789</AccountNumber>
<BranchNumber>004</BranchNumber>
<TransitNumber>01646</TransitNumber>
<NameAndCity>XYZ Bank</NameAndCity>
<OwnerFullName>ABC XYZ</OwnerFullName>
</Info>
<Info>
<AccountNumber>23456789</AccountNumber>
<BranchNumber>004</BranchNumber>
<TransitNumber>01646</TransitNumber>
<NameAndCity>333 Bank</NameAndCity>
<OwnerFullName>ABC XYZ</OwnerFullName>
</Info>
$ sed -r '/.*333 /!s#^(\s*<[^>]+>).*(</[^>]+>)$#\133333\2#;s|^(\s*<[^>]+>333 ).*(</[^>]+>)$|\133333\2|' file.txt
<Info>
<AccountNumber>33333</AccountNumber>
<BranchNumber>33333</BranchNumber>
<TransitNumber>33333</TransitNumber>
<NameAndCity>33333</NameAndCity>
<OwnerFullName>33333</OwnerFullName>
</Info>
<Info>
<AccountNumber>33333</AccountNumber>
<BranchNumber>33333</BranchNumber>
<TransitNumber>33333</TransitNumber>
<NameAndCity>333 33333</NameAndCity>
<OwnerFullName>33333</OwnerFullName>
</Info>首先,用">333 "否定包含/.*333 /!的字符串。这些字符串将受到第二个regex s#^(\s*<[^>]+>).*(</[^>]+>)$#\133333\2#;的影响。其中包含">333 "的字符串将根据s|^(\s*<[^>]+>333 ).*(</[^>]+>)$|\133333\2|进行更改。
将-i选项添加到sed以应用更改。
编辑:
正如@Tiw所评论的,最好使用perl而不是sed:
$ perl -pe 's#<([^>]+)>(?:(?!333).)*</\1>#<\1>333333333<\1>#;s#<([^>]+)>333 .*#<\1>333 3333</\1>#' -i file.txt
<Info>
<AccountNumber>333333333<AccountNumber>
<BranchNumber>333333333<BranchNumber>
<TransitNumber>333333333<TransitNumber>
<NameAndCity>333333333<NameAndCity>
<OwnerFullName>333333333<OwnerFullName>
</Info>
<Info>
<AccountNumber>333333333<AccountNumber>
<BranchNumber>333333333<BranchNumber>
<TransitNumber>333333333<TransitNumber>
<NameAndCity>333 3333</NameAndCity>
<OwnerFullName>333333333<OwnerFullName>
</Info>注意:-i选项将更改应用于文件。
发布于 2019-01-27 07:33:55
与所有正确的细节一起张贴给未来的用户:
perl -pe 's#<([^>]+)>(?:(?!333).)*</\1>#<\1>333333333<\1>#;s#<([^>]+)>333 .*#<\1>333 3333</\1>#' -i file.txt上面将用333333333替换所有的标记值,即使这不是AccountNumber,BranchNumber..etc标记,它也将替换其他标记值。另外,NameAndCity和OwnerFullName是字母数字,所以我们需要为它们添加带有字母数字/特殊/空间的Regex。以下是答案:
perl -i -pe 'unless (/333/) {s#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>33333333</AccountNumber>#;
s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;
s#<TransitNumber>[0-9]*</TransitNumber>#<TransitNumber>3333333</TransitNumber>#;
s#<NameAndCity>[A-Za-z\ \-\+]*</NameAndCity>#<NameAndCity>333 33333</NameAndCity>#;
s#<OwnerFullName>[A-Za-z/\/\ \+]*</OwnerFullName>#<OwnerFullName>3333 33333</OwnerFullName>#;}' test.txt https://stackoverflow.com/questions/54378905
复制相似问题