Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用sed删除两个匹配模式之间的所有行_Regex_Sed - Fatal编程技术网

Regex 使用sed删除两个匹配模式之间的所有行

Regex 使用sed删除两个匹配模式之间的所有行,regex,sed,Regex,Sed,我有一个类似以下内容的文件: # ID 1 blah blah blah blah $ description 1 blah blah # ID 2 blah $ description 2 blah blah blah blah sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p" 如何使用sed命令删除#和$行之间的所有行?因此,结果将是: # ID 1 $ description 1 blah blah # ID 2 $ descri

我有一个类似以下内容的文件:

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
如何使用sed命令删除
#
$
行之间的所有行?因此,结果将是:

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

请您也解释一下好吗?

我很久以前就做过类似的事情,它是这样的:

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
这有点像:

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
  • -n
    抑制所有输出
  • -e“1,/#ID 1/p”
    从第一行开始执行,直到您的图案和p(打印)
  • -e/\$description 1/,$p“
    从第二个模式执行,直到结束和p(打印)

我可能对字符串的某些转义错误,因此请仔细检查。

使用此sed命令来实现:

sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt
Mac用户(为了防止在d命令末尾出现额外字符)需要在右括号前添加分号

sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt
输出 说明:
  • /^#//,/^\$/
    将匹配以
    开头的行与以
    $
    开头的行之间的所有文本<代码>^
    用于行首字符<代码>$是一个特殊字符,因此需要转义
  • /^#/表示如果行首不是
    #
  • /^$/表示如果行的开头不是
    $
  • d
    表示删除

因此,总体而言,它首先匹配从
^
^\$
的所有行,然后从这些匹配行中查找不匹配的行
^
不匹配的行
^\$
,并使用
d

使用sed的另一种方法删除它们:

$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3
sed '/^#/,/^\$/{//!d;};' file
  • /^#/,/^\$/
    :从以
    开头的行到以
    $
    开头的下一行
  • /!d
    :删除除与地址模式匹配的行以外的所有行

在一般形式下,如果您有一个包含abcde格式内容的文件,其中a节在模式b之前,c节在模式d之前,e节在模式d之后,并且您应用以下
sed
命令,则会得到以下结果

在本演示中,输出由
=>abcde
表示,其中的字母表示输出中将包含哪些部分。因此,
ae
仅显示部分a和e的输出,
ace
将是部分a、c和e等

请注意,如果输出中出现
b
d
,则这些是出现的模式(即,它们被视为输出中的部分)

另外,不要将
/d/
模式与命令
d
混淆。在这些演示中,命令始终位于末尾。模式始终介于
/
之间

  • sed-n-e'/b/,/d/!p'abcde
    =>ae
  • sed-n-e'/b/,/d/p'abcde
    =>bcd
  • sed-n-e'/b/,/d/{/!p}'abcde
    =>c
  • sed-n-e'/b/,/d/{//p}'abcde
    =>bd
  • sed-e'/b/,/d/!d'abcde
    =>bcd
  • sed-e'/b/,/d/d'abcde
    =>ae
  • sed-e'/b/,/d/{/!d}'abcde
    =>abde
  • sed-e'/b/,/d/{//d}'abcde
    =>ace

    • 下面的示例删除了“if”“end if”之间的行

      扫描所有文件,并删除两个匹配模式之间的行(包括它们)


      对于Mac用户:为了防止在d命令的结尾出现额外字符,您需要在结束括号前添加分号,
      sed'/^#/,/^\$/{/^#/!{/^\$/!d;}file.txt
      作为@sleport的解决方案更简洁。这就是进行向下投票的原因吗?如果你喜欢答案,那就投票吧。向下投票通常是针对一些不能解决OP问题的答案,既然OP已经接受了这个答案,这意味着它对OP有效。不是吗?如果你想删除#和$行,你会怎么做?如果您想在一行末尾找到$,可以使用$\$,然后只需使用:
      sed'/^#/,/^\$/d'文件
      这在300mb文件上运行的速度令人印象深刻。我说的是SSD上的瞬间。我有点困惑,因为我不熟悉sed语法。尚不清楚第一个和第二个sed命令是否没有依赖关系,即两者之间的区别在于是否要保留匹配标记。在测试之前,我一直假设第一个命令删除了令牌之间的所有内容,第二个命令删除了令牌本身。如果您试图在令牌之间删除块,只需使用第二个命令/end/,$p'
      完全打乱了我的工作流程,因为我依赖于这项工作。这对我根本不起作用。这条线有问题。我错过什么了吗?因为对我来说,它看起来就像你在回答@Lri中所显示的那样。实际有效的解决方案如下:
      sed'/PATTERN-1/,/PATTERN-2/{//!d}'input.txt
      你如何做到这一点,包括模式?试试这个:
      sed'/^#/,/^\$/d;'文件