Регулярное выражение "оно не начинается с KEYWORD1" - PullRequest
2 голосов
/ 23 января 2012

Рассмотрим возможность экспорта запроса MySQL.

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)

Я хотел бы обработать этот файл mysqlqtee.txt с помощью sed или perl, фильтруя только фактические строки данных.

Я могу сказать 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)

Кажется, я не могу перевести "ЭТО НЕ НАЧИНАЕТСЯ" с части в регулярное выражение. Двойное использование ^ означает НЕТ и LINE_START одновременно вызывает проблемы. Я могу отменить начальную букву с помощью s/^[^\|]/, но это также оставляет строку заголовка вне.

Мне удалось сделать это в perl, используя оператор IF. Но это все еще беспокоит меня слишком сильно, что я не мог сделать это с одним s///g. Можно ли это сделать таким образом?

Как мне перевести "С ЭТОГО НАЧИНАЕТСЯ" часть в регулярное выражение? Хорошо подходит решение sed или perl!

Ответы [ 5 ]

3 голосов
/ 23 января 2012

Эта задача облегчается, если вы используете упреждающий взгляд. Вместо использования группы захвата, просто подтвердите, что текст является или не является тем, что вы ищете.

Прокомментируйте строки:

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

Прокомментируйте все остальные строки:

perl -pi.old -e's/^(?!\| AB)/#/' mysqlqtee.txt
2 голосов
/ 23 января 2012

Вы можете отменить регулярное выражение с помощью 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)
1 голос
/ 23 января 2012

Будет ли это работать для вас -

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)
1 голос
/ 23 января 2012

В регулярных выражениях нет отрицания, но вы обладаете всей мощью всего языка программирования, поэтому используйте его:

perl -pi.old -e '/(^\| AB.*)/ or $_ = "#$_"' mysqlqtee.txt
0 голосов
/ 23 января 2012

Чтобы соответствовать символу '|', используйте \| (класс символов [|] также будет работать); чтобы соответствовать любому символу , кроме '|', используйте класс символов с отрицанием [^|].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...