使用sed删除在找到字符串之前和之后的行

时间:2017-06-07 07:23:23

标签: awk sed

下面是我的xml文件内容 -

<?xml version="1.0" encoding="UTF-8"?>
<artifactListing>
    <folder id="REPORTMART" path="/Repository Objects" pathAlias="/00"
        modifiedBy="Maria" lastUpdated="1480426973000" description="Hyperion Root Folder"/>
    <folder id="DATASOURCESFOLD"
        path="/Repository Objects/HRInternalFolder/DataSources"
        pathAlias="/00/HRInternal/DataSources" modifiedBy="Maria" lastUpdated="1492814854000"/>
    <folder id="HRINTERNALFOLD"
        path="/Repository Objects/HRInternalFolder"
        pathAlias="/00/HRInternal" modifiedBy="Maria" lastUpdated="1492814854000"/>
    <folder id="00000158e031595b-0000-0782-0ae57730"
        path="/Repository Objects/TRCS" pathAlias="/00/0"
        modifiedBy="demoadmin" lastUpdated="1492814854000" description="TRCS"/>
    <resource id="JavaScriptUpdateResizeOn_dds_js"
        path="/Repository Objects/Administration/Impact Manager/Script Repository"
        pathAlias="/00/Administration/0/Script_Repository"
        modifiedBy="Maria" lastUpdated="1492814880000"
        description="JavaScript Update DDS configuration with Layout Manager"
        name="JavaScriptUpdateResizeOn_dds.js" type="text/im-javascript" size="-1"/>
    <resource id="449cb46e6b4492f3afb8ef693dffb43a90cdd992"
        path="/Security" pathAlias="/02"
        description="Shared Services Administrator"
        name="epm_default_cloud_admin" type="UserPreferences" size="-1"/>
    <resource id="0f62187cf5a8f5aecec7a9879c9e40497d6d8649"
        path="/Security" pathAlias="/02" description="" name="Jacob"
        type="UserPreferences" size="-1"/>
    <resource id="0df02da8548eeef2174c97c2ade67b4c5adc3160"
        path="/Security" pathAlias="/02" description="" name="Henry"
        type="UserPreferences" size="-1"/>
    <resource id="33dca1c0c1c5ae78f67580a76d9c6aba6a172e20"
        path="/Security" pathAlias="/02" description="" name="Susan"
        type="UserPreferences" size="-1"/>
    <resource id="3e182b1ea9376483a38614d916a0b666ef531b6d"
        path="/Security" pathAlias="/02" description="" name="Maria"
        type="UserPreferences" size="-1"/>
    <resource id="0f62187cf5a8f5aecec7a9879c9e40497d6d8649"
        path="/Security" pathAlias="/02" description="" name="Jacques"
        type="UserPreferences" size="-1"/>
    <resource id="0df02da8548eeef2174c97c2ade67b4c5adc3160"
        path="/Security" pathAlias="/02" description="" name="Frank"
        type="UserPreferences" size="-1"/>
    <resource id="PP_3e182b1ea9376483a38614d916a0b666ef531b6d_0"
        path="/Product Preferences" pathAlias="/05"
        description="This is your default Personal Page."
        name="My Personal Page" type="PersonalPageContent" size="-1"/>
</artifactListing>

现在使用sed我想删除整个资源标签,如果&#34; Susan&#34;在其中找到字符串,不应考虑其他非Susan资源标记。 在这种情况下,它在字符串之前和之后只有1行,而在资源标记中有更多行的其他情况下。

3 个答案:

答案 0 :(得分:1)

使用XML解析器是操作XML文档的正确方法。

xmlstarlet解决方案:

xmlstarlet ed -d '//resource[@name="Susan"]' yourxmlfile
  • ed - 编辑模式

  • -d - 删除操作

  • //resource[@name="Susan"] - xpath表达式

答案 1 :(得分:0)

尝试:

awk '/resource id/{B=1} /name="Susan"/{B="";VAL=""} B{VAL=VAL?VAL ORS $0:$0;} B && NR>1{print VAL;VAL="";}'   Input_file

EDIT1:添加非单行形式的解决方案也有解释。

awk '/resource id/{              ####Searching for string resource id in a line. If it is found then do following.
                        B=1      ####Setting variable B to 1 value here.
                  }
     /name="Susan"/{             ####Searching for string name="Susan" here, if that is found in any of the line then perform following.
                        B="";    ####Nullifying variable B value here.
                        VAL=""   ####Nullifying variable VAL here too.
                   }
     B{                          ####Checking if variable B value is NOT NUL.
        VAL=VAL?VAL ORS $0:$0;   ####creating variable VAL value if its present then by concatenating it with current line value or if it is null assigning the $0.
      }
     B && NR>1{                  ####If B value is NOT NULL and NR(Number of line) is greater than 1 then perform following.
                print VAL;       ####printing the variable VAL here.
                VAL="";          ####Nullifying variable VAL here.
              }
    '  Input_file                ####Mentioning the Input_file here.

EDIT2:由于OP改变了样本输入,所以这里也改变了一些代码。

awk '/resource id/{q=$0;B=1;getline;if($0 ~ /name="Susan"/){B="";VAL=""} else {print q;B=1}} B{VAL=VAL?VAL ORS $0:$0;} B && NR>1{print VAL;VAL="";}'   Input_file

EDIT3: OP现在修改了帖子,所以更改了上面的一些代码。

awk '/resource id/{q=$0;B=1;getline;if($0 ~ /name="Susan"/){B="";VAL=""} else {print q;B=1}} B{VAL=VAL?VAL ORS $0:$0;} B && NR>1{print VAL;VAL="";next} 1'   Input_file

答案 2 :(得分:0)

对于您的方案,请尝试以下操作:

$ sed -ibak -r '/^\s*<resource/!bend;:loop;N;/\/>.*$/{/Susan/d;bend};bloop;:end' filename

说明:

  1. /^\s*<resource/!bend:如果pattern space不以^\s*<resource开头,请跳转到名为end的标签以开始新的循环。
  2. :loop:设置一个名为loop的标签来处理整个resource代码。
  3. N:使用N命令将\nnext line附加到pattern space
  4. /\/>.*$/{/Susan/d}:如果当前pattern space/>$结尾,这意味着我们在resource中有一个完整的pattern space标记,那么我们可以处理它;如果此完整resource标记包含Susan,即pattern,请使用d命令删除pattern space中的所有内容,然后跳转到名为{{的标签1}}开始一个新的循环。
  5. end:使用循环将当前bloop标记的其余行追加到resource
  6. 使用pattern space备份源文件。
  7. P.S:它还适用于资源标签中有更多行的其他情况。