“它不是以KEYWORD1开头”的正则表达式

时间:2012-01-22 20:05:30

标签: regex perl sed

考虑一个MySQL查询的tee导出。

SELECT * FROM mytable;
+----------+-------+----------+-----------+-------+------+--------+
| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
+----------+-------+----------+-----------+-------+------+--------+
| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
     *
     *
     *
| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
+----------+-------+----------+-----------+-------+------+--------+
9995 rows in set (0.04 sec)

我想通过sed或perl处理这个mysqlqtee.txt文件,只过滤实际的数据行。

我可以告诉sed或perl:“请注释掉以”| AB“的静态文本开头的每一行!

sed -i '.old' 's/\(^\| AB.*\)/#\1/g' mysqlqtee.txt
perl -pi.old -e 's/(^\| AB.*)/#$1/g' mysqlqtee.txt

这些让我:

SELECT * FROM mytable ORDER BY timecode;
+----------+-------+----------+-----------+-------+------+--------+
| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
+----------+-------+----------+-----------+-------+------+--------+
#| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
#| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
     *
     *
     *
#| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
#| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
+----------+-------+----------+-----------+-------+------+--------+
9995 rows in set (0.04 sec)

很好地评论所有实际的数据行,并保持其他所有行不变。

到目前为止,我无法告诉Perl或者sed是:“请注释除了”| AB“的静态文本以外的所有内容,请注意! 哪个会让我:

#SELECT * FROM mytable ORDER BY timecode;
#+----------+-------+----------+-----------+-------+------+--------+
#| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
#+----------+-------+----------+-----------+-------+------+--------+
| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
     *
     *
     *
| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
#+----------+-------+----------+-----------+-------+------+--------+
#9995 rows in set (0.04 sec)

我似乎无法将“IT DOES NOT WITH START”部分翻译成regexp。 同时使用^表示NOT和LINE_START会造成麻烦。 我可以用s/^[^\|]/来否定起始字母,但这也会将标题行排除在外。

我设法使用IF语句在perl中执行此操作。 但它仍然让我感到太过烦恼,以至于我无法用一个s///g做到这一点。 这可以这样做吗?

如何将“IT不会开始”部分转换为regexp? sed或perl解决方案都没问题!

5 个答案:

答案 0 :(得分:3)

如果您使用前瞻,这项任务很容易。而不是使用捕获组,只是断言文本是,或不是你寻求的。

评论这些行:

perl -pi.old -e's/^(?=\| AB)/#/' mysqlqtee.txt

评论所有其他行:

perl -pi.old -e's/^(?!\| AB)/#/' mysqlqtee.txt

答案 1 :(得分:2)

您可以将sed添加到!之后取消正则表达式:

sed -i.old '/^| AB/!s/^/#/' mysqltree.txt

输出

$ sed '/^| AB/!s/^/#/' mysqltree.txt
#SELECT * FROM mytable;
#+----------+-------+----------+-----------+-------+------+--------+
#| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
#+----------+-------+----------+-----------+-------+------+--------+
| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
#+----------+-------+----------+-----------+-------+------+--------+
#9995 rows in set (0.04 sec)

答案 2 :(得分:1)

regexp中没有否定,但你拥有整个编程语言的所有功能,所以使用它:

perl -pi.old -e '/(^\| AB.*)/ or $_ = "#$_"' mysqlqtee.txt

答案 3 :(得分:1)

这对你有用吗?

sed -i.bak '/^+--/,/^+--/s/^/#/;1s/^/#/' file
           |____________|     |___| 
                 |              |
          This defines a    This identifies
          regex range.       the first line
  • 对于我们的简单替换,我们提供了两个标记。首先是regex range。此范围表示从以+--开头的行开始,直到找到另一行为止。对于所有这些行,在它前面放置一个#。因此,SQL查询后直到数据开头的行会在它们前面获得#。此外,由于正则表达式范围从文件的最末端开始,因此它开始标记#。由于没有遇到结束范围,因此它将标记到文件结尾
  • 第二个标记是行号。由于我们希望将#放在SQL语句的前面,我们告诉sed查看第一行以及可能的内容,将#放在它前面。

INPUTFILE:

[jaypal:~/Temp] cat file
SELECT * FROM mytable;
+----------+-------+----------+-----------+-------+------+--------+
| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
+----------+-------+----------+-----------+-------+------+--------+
| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
     *
     *
     *
| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
+----------+-------+----------+-----------+-------+------+--------+
9995 rows in set (0.04 sec)

测试:您可以使用-i option备份原始文件或将以下输出重定向到另一个文件。

[jaypal:~/Temp] sed '/^+--/,/^+--/s/^/#/;1s/^/#/' file
#SELECT * FROM mytable;
#+----------+-------+----------+-----------+-------+------+--------+
#| label1   | lbl2  | label3   | label4    | lbl5  | lbl6 | label7 |
#+----------+-------+----------+-----------+-------+------+--------+
| ABCDEFGH | YNNYY | 0.001596 |  0.161152 |     2 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001404 |  0.162774 |     3 |    1 | a      |
     *
     *
     *
| ABCDEFGH | YNNYY | 0.001286 | 10.941642 |  5999 |    1 | a      |
| ABCDEFGH | YNNYY | 0.001315 | 10.942950 |  6000 |    1 | a      |
#+----------+-------+----------+-----------+-------+------+--------+
#9995 rows in set (0.04 sec)

答案 4 :(得分:0)

要匹配字符“|”,请使用\|(字符类[|]也可以);要匹配'|'之外的任何字符,请使用否定的字符类[^|]