Solaris,版本:11.10.0,版本= 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
任何帮助将不胜感激。
答案 0 :(得分:1)
尝试一下:
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>
一种非常简单的方法,如果您测试正常并且想要就地更改文件,请添加-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
您可以自己添加其他高度。 #
是要替换/
的常规s
,这是一种避免在封闭标签(IE /
)中逃脱s#from#to#;
的简便方法。
这很简单,所以我认为您不会遇到困难:)
添加-i
开关以进行就地更改,例如:perl -i -pe '...
。
答案 1 :(得分:1)
$ 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 /!
的字符串。这样的字符串将受到第二个正则表达式s#^(\s*<[^>]+>).*(</[^>]+>)$#\133333\2#;
的影响。确实包含">333 "
的字符串将根据s|^(\s*<[^>]+>333 ).*(</[^>]+>)$|\133333\2|
进行更改。
在sed中添加-i选项以应用更改。
编辑:
正如@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选项将所做的更改应用于文件。
答案 2 :(得分:1)
张贴所有正确的详细信息,以供将来的用户使用:
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