首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在文本文件中的特定模式之后替换请求值?

如何在文本文件中的特定模式之后替换请求值?
EN

Stack Overflow用户
提问于 2019-01-26 13:40:05
回答 3查看 88关注 0票数 1

Solaris,版本: 11.10.0,REV=2005.01.21.15.53

我有一个文件test.txt,它包含如下所示的值:

代码语言:javascript
复制
 <Info>
     <AccountNumber>23456789</AccountNumber>
     <BranchNumber>004</BranchNumber>
     <TransitNumber>01646</TransitNumber>
     <NameAndCity>XYZ Bank</NameAndCity>
     <OwnerFullName>ABC XYZ</OwnerFullName>
  </Info>

所有的信息都在一条线上,我们有像上面这样的多行,其他标签也是可用的。

它还包含其他标记值。另外,如果标记值包含"333“组合,我不想替换它们。

我想使用sed命令将标记的值替换为33333,替换后,我希望将更新后的信息保存到同一个文件中。

产出应是:

代码语言:javascript
复制
 <Info>
     <AccountNumber>33333333</AccountNumber>
     <BranchNumber>33333</BranchNumber>
     <TransitNumber>3333333</TransitNumber>
     <NameAndCity>333 33333</NameAndCity>
     <OwnerFullName>3333 33333</OwnerFullName>
  </Info>

我对shell脚本很陌生,不完全能够编写与之匹配的模式。

到目前为止,我已经实现了前两个标记值,但它不起作用:

代码语言:javascript
复制
sed 's/(<AccountNumber>)\+[0-2,4-9]*$/\1 33333333/' test.txt
sed 's/(<BranchNumber>)\+[0-2,4-9]*$/\1 33333/' test.txt

任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-26 13:52:31

试试这个:

代码语言:javascript
复制
sed -e '/333/!{' -e 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#;s#<BranchNumber>[0-9]*</BranchNumber>#<BranchNumber>33333</BranchNumber>#;}'

例:

代码语言:javascript
复制
$ 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,看看它是否有效:

代码语言:javascript
复制
perl -pe 's#<AccountNumber>[0-9]*</AccountNumber>#<AccountNumber>333333333</AccountNumber>#' test.txt

如果它有效的话,我们可以添加其他的。

因此,对于你的逻辑首先写在问题中,应该是这样的:

代码语言:javascript
复制
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 '...

票数 1
EN

Stack Overflow用户

发布于 2019-01-26 14:37:45

代码语言:javascript
复制
$ 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:

代码语言:javascript
复制
$ 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选项将更改应用于文件。

票数 1
EN

Stack Overflow用户

发布于 2019-01-27 07:33:55

与所有正确的细节一起张贴给未来的用户:

代码语言:javascript
复制
perl -pe 's#<([^>]+)>(?:(?!333).)*</\1>#<\1>333333333<\1>#;s#<([^>]+)>333 .*#<\1>333 3333</\1>#' -i file.txt

上面将用333333333替换所有的标记值,即使这不是AccountNumber,BranchNumber..etc标记,它也将替换其他标记值。另外,NameAndCity和OwnerFullName是字母数字,所以我们需要为它们添加带有字母数字/特殊/空间的Regex。以下是答案:

代码语言:javascript
复制
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 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54378905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档