【问题标题】:Delete data between two lines inclusive删除两行(含)之间的数据
【发布时间】:2012-12-28 22:31:01
【问题描述】:

在两行文本(包括第一行但不包括第二行)之间搜索和删除数据的最佳方法是什么。

字符串 1:SECTION - PAY 500 - 待删除

要删除的数据,随机的文本行

字符串 2:SECTION - Pay 400 - 停留

这是一个大约 3000 页的 word 文档,但我也有一个文本版本可以使用。我应该从哪里开始为这样的任务编写 bash 脚本?

文件内容示例:

text 
SECTION - PAY 500    (to be deleted)
text                 (to be deleted)
SECTION - Pay 400
text 
SECTION - PAY 500    (to be deleted)
text                 (to be deleted)
SECTION - Pay 400
text 

删除后应该是这个结果

text 
SECTION - Pay 400
text
SECTION - Pay 400
text

【问题讨论】:

  • 假设您要从 3000 页文档中删除大量块,您能否再给我们一些示例。您希望删除多少块?部分标记中的文本之间是否存在歧义,即 SECTION - PAY 5000 ?祝你好运。
  • sed 将是我去这里。

标签: bash shell unix


【解决方案1】:

标准sed的解决方案:

sed "/$START/,/$END/ { /$END/"'!'" d; }"

这意味着对于从/$START/ 开始到/$END/ 结束的范围,将执行{ /$END/! d; } 操作,对所有不是/$END/ 的行执行d(删除)。

"'!'" 很奇怪,但这是从 bash 扩展中逃脱 ! 符号的唯一方法。

【讨论】:

    【解决方案2】:

    我认为您可以很快地逐行解析文件。您要归档的内容似乎并不复杂,无法实现。

    copy=true
    while read line; do
        if [ $copy ]; then
            if [[ "$line" == "SECTION - PAY 500"* ]]; then copy=; continue; fi
            echo "$line" >> outputfile
        else
            if [[ "$line" == "SECTION - Pay 400"* ]]; then copy=true; fi
        fi
    done < inputfile
    

    通过这样做,我们现在甚至拥有一台小型图灵机!

    【讨论】:

      【解决方案3】:

      另一个(不那么奇怪;))标准 sed 解决方案: sed "/$END/ p; /$START/,/$END/ d;"

      附注:如果需要,某些sed 版本还支持文件的就地编辑。

      还有一个成熟的 bash 脚本:

      #! /bin/bash
      
      if [ "x$1" = "x-r" ]
      then
          regex=1
          shift
      else
          regex=0
      fi
      
      if [ $# -lt 2 ]
      then
          echo "Usage: del.sh [-r] start end"
          exit 1
      fi
      
      start="$1"
      end="$2"
      
      function matches
      {
          [[ ( regex -eq 1 && "$1" =~ $2 ) || ( regex -eq 0 && "$1" == "$2" ) ]]
      }
      
      del=0
      while read line
      do
          # end marker, must be printed
          if matches "$line" "$end"
          then
              del=0
          fi
          # start marker, must be deleted
          if matches "$line" "$start"
          then
              del=1
          fi
          if [ $del -eq 0 ]
          then
              echo "$line"
          fi
      done
      

      【讨论】:

        【解决方案4】:

        简单的解决方法:试试这个方法

        Inputfile.txt

        text 
        SECTION - PAY 500    
        text                 
        SECTION - Pay 400
        text 
        SECTION - PAY 500   
        text                 
        SECTION - Pay 400
        text
        

        代码

        awk '/500/{print;getline;next}1' Inputfile.txt | sed '/500/d'
        

        输出

        text 
        SECTION - Pay 400
        text 
        SECTION - Pay 400
        text 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多