#regex #perl
#регулярное выражение #perl
Вопрос:
У меня есть файл под названием test.txt
12/15-12:24:51 <1692> @@ 0 0 0 0 0 0 0 0 0 0 691 0
12/15-12:24:51 <1692> END SESSION SUMMARY
12/15-12:24:55 <1692> INFO: SESSION SUMMARY
12/15-12:24:55 <1692> - ch G B C L S T X Y -
12/15-12:24:55 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:24:55 <1692> END SESSION SUMMARY
12/15-12:24:59 <1692> INFO: SESSION SUMMARY
12/15-12:24:59 <1692> - ch G B C L S T X Y -
12/15-12:24:59 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:24:59 <1692> END SESSION SUMMARY
12/15-12:25:03 <1692> INFO: SESSION SUMMARY
12/15-12:25:03 <1692> - ch G B C L S T X Y -
12/15-12:25:03 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:25:03 <1692> END SESSION SUMMARY
12/15-12:25:07 <1692> INFO: SESSION SUMMARY
12/15-12:25:07 <1692> - ch G B C L S T X Y -
12/15-12:25:07 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:25:07 <1692> END SESSION SUMMARY
и нужен вывод в виде
12/15-12:24:51 <1692> @@ 0 0 0 0 0 0 0 0 0 0 691 0
12/15-12:24:55 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:24:59 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:25:03 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
12/15-12:25:07 <1692> @@ 0 0 0 0 0 0 0 0 0 0 692 0
Попробовал следующий способ, но не смог получить
cat test.txt | perl -e '$str = do { local $/; <> }; while ($str =~ /(dd):(dd):(dd)?s.*/) { print "$1:$2:$3:$4n"}'
Комментарии:
1. Похоже, вы просто хотите grep для
@@
.
Ответ №1:
В вашем однострочнике есть несколько ошибок. Я пройдусь по ним, а затем покажу вам решение.
cat test.txt |
Вам не нужно подключаться к каналу, просто используйте имя файла в качестве аргумента при использовании diamond operator <>
.
perl -e '$str = do { local $/; <> };
Это преобразует весь файл в одну строку. В вашем случае это бесполезно. Это полезно только в том случае, если вы ожидаете совпадений, которые включают новые строки.
while ($str =~ /(dd):(dd):(dd)?s.*/) {
Эта часть будет запущена только один раз, потому что вы не использовали /g
модификатор. Это особенно плохо, поскольку вы не работаете в построчном режиме, потому что вы проглотили файл.
Я полагаю, регулярное выражение попытается сопоставить одну из временных меток, например 12:25:07
. Почему вы хотели бы это сделать, вне моего понимания, поскольку каждая строка вашего ввода имеет такую временную метку, что делает всю операцию бесполезной. Вы хотите попытаться сопоставить что-то уникальное для нужных вам строк.
print "$1:$2:$3:$4n"}'
В этой части печатаются 4 группы захвата, а у вас их всего 3 (2 фиксированные и 1 дополнительная). Он не будет печатать всю строку.
То, что вы хотите, это что-то упрощенное, как это:
perl -ne'print if /@@/' test.txt
Который будет проходить через файл построчно, проверять каждую строку @@
и печатать найденные строки.
Или, если вы используете *nix, просто grep '@@' test.txt