Bash 使用sed替换模式

Bash 使用sed替换模式,bash,sed,Bash,Sed,如何编写bash脚本来执行以下操作 在以html和htm结尾的目录中递归搜索所有文件 使用sed搜索并删除此行之前的所有行,包括行 以及搜索并删除之后的所有行,包括行 更改不应在同一个文件上,而应与index-temp.html类似 我写了下面的内容,但我不知道如何在更改后更改整个块,并将更改安全地保存到另一个文件,而不是同一个文件上。我必须使用if吗 #!/bin/bash input=$1 find "$input" -type f -name "*.htm" -exec sed 对于单

如何编写bash脚本来执行以下操作

  • 在以html和htm结尾的目录中递归搜索所有文件
  • 使用sed搜索
    并删除此行之前的所有行,包括
  • 以及搜索
    并删除之后的所有行,包括
  • 更改不应在同一个文件上,而应与index-temp.html类似
  • 我写了下面的内容,但我不知道如何在更改后更改整个块,并将更改安全地保存到另一个文件,而不是同一个文件上。我必须使用if吗

    #!/bin/bash
    input=$1
    find "$input" -type f -name "*.htm" -exec sed 
    

    对于单个文件,sed命令为:

    sed '1,/<body>/d;/<\/body>/,/$/d' index.html > index-temp.html
    
    其中,ROWa是要开始的行号,ROWz是要结束的行号,从1开始计算。美元可用于最后一行

    您也可以使用模式:

    sed '/PATa/,/PATz/ d' 
    
    从pattern PATa到pattern PATz。图案/线条可以混合

    现在,查找部分:

    find "$input" -type f -name "*.htm*" -exec sed -i.temp '0,/<body>/d;/<\/body>/,/$/d' {} ";" 
    
    正如@Tom Fenech所说:

    xmllint --html --xpath '//body/node()' index.htm* > index-temp.html
    
    • 是目标
    • *.html?(l)
      仅适用于htm/html,但extglob处于活动状态(debian默认)
    有关@tripleee的详细信息:

    find "$input" -type f -iregex '.*\.html?' \
      -exec sh -c 'for f; do
          xmllint --html --xpath "//body/node() "$f" >"${f%.htm*}"-temp.html;
        done' _ {} +
    

    毫无疑问,您可能是指
    sed
    而不是
    sid
    。假设您的文件是(合理地)有效的HTML,您可能应该使用HTML解析工具来提取
    标记的内容。例如
    xmllint--html--xpath'//body/node()'file.htm
    可能会满足您的需要。可能重复“使用
    sed
    搜索
    并删除此行之前的所有行,包括
    行”——此要求定义不明确。
    主体
    元素(即
    )的开始标记允许具有属性(
    等)。搜索
    可能无法找到它。此外,也不能保证它是单独在线的。删除整行可能太多。这实际上不是
    sed
    的工作,您没有正确定义它,因为您是用
    sed
    术语来考虑它的(即逐行处理文件)。
    0,
    模式是GNU
    sed
    扩展,我相信。@tripleee:我解释说它从1开始计算,但写“0”(它默默地工作)但是我改正了。如果
    ?如果
    etc
    ,所有内容都在一行上呢?编辑HTML绝对不是
    sed
    @axiac:
    echo“etc”| sed'0,//d;///$/d'
    根据要求不返回任何内容:删除此行之前的所有行(包括该行),并删除该行之后的所有行(包括该行)。您发现了什么,哪些违反了这些要求,或者您使用了什么样的线定义?问题是关于
    使用sed搜索
    ,而不是搜索body标签。如果您有不同的要求,请提出您自己的问题。@axiac:我知道您也要求IT对该问题进行澄清,这是正确的方式。但是,只要您不是上述html文件的生产者,并且更好地了解需求,您的结论就为时过早。如果没有确认,只逐行搜索
    的想法太狭隘,你不应该批评答案。或者
    查找-执行官sh-c'代表f;doxmllint--html--xpath”//body/node()“$f”>“${f%.htm*}”-temp.html;done'{}+
    …虽然
    *.htm?
    匹配
    html
    htmq
    ,但不只是
    htm
    ;如果当前目录中有匹配的文件,您的shell将展开匹配。您需要
    -iregex.*\.html?
    或类似的东西,并带有引号。我必须使用sed,而不是使用xmllint
    find "$input" -type f -name "*.htm" -exec ./justbody.sh {} ";" 
    
    xmllint --html --xpath '//body/node()' index.htm* > index-temp.html
    
    find "$input" -type f -iregex '.*\.html?' \
      -exec sh -c 'for f; do
          xmllint --html --xpath "//body/node() "$f" >"${f%.htm*}"-temp.html;
        done' _ {} +