sed / awk:删除与单词后面没有其他单词匹配的所有行

时间:2014-03-14 15:30:16

标签: regex bash replace sed awk

我的档案中有以下几行。

<stuff>
test1.*test2
test1
test1.*test2
test1
<other stuff>

我想删除包含test1的所有行,但不会删除test2 - 这意味着我最终应该:

<stuff>
test1.*test2
test1.*test2
<other stuff>

我尝试了很多正则表达式,但似乎无法破解sed或awk。这是我在使用vim regexp进行测试后的最新尝试。

sed -i .bk '/^.*test1\(\(test2\)\@!.\)*$/d' file

(这是Mac OS X上bash脚本的一部分)

4 个答案:

答案 0 :(得分:3)

使用两个表达式。第一个跳过test1后跟test2的情况,第二个删除test1 - 只有在test2不存在时才能到达。

sed -e '/test1.*test2/b' -e '/test1/d'

答案 1 :(得分:2)

尝试类似:

awk '/test1/&&!/test2/{next}1' file

我们告诉awk:

  • 使用test1查找行。
  • 同一行test2不应该出现
  • 如果找到这样的行,我们跳过
  • 如果找不到这样的行,我们打印

$ cat file
<stuff>
test1.*test2
test1
test1.*test2
test1
<other stuff>

$ awk '/test1/&&!/test2/{next}1' file
<stuff>
test1.*test2
test1.*test2
<other stuff>

答案 2 :(得分:1)

使用perl正则表达式的GNU grep:

grep -vP 'test1(?!.*test2)' file

答案 3 :(得分:1)

$ awk '!/test1/||/test2/' file
<stuff>
test1.*test2
test1.*test2
<other stuff>