Почему Perl regex \ K не исключает шаблон, сопоставленный до \ K? - PullRequest
2 голосов
/ 14 июля 2020

У меня есть файл под названием test.txt со следующим текстом:

> Last login: Mon Jul 13 05:09:33 2020 You have mail.   
> ******************************
> cat, you have just logged into machine sampleserver2    
> ******************************
> 
> --------------------------------------------------------------  
> | To switch environments later, run:                         |
> |                                                            |
> | change                                                     |
> |                                                            |
> --------------------------------------------------------------
> 
> 
> Current Dir => /apps/users/cat     Oracle SID: SAMPLE
> cat@sampleserver2:

Я пытаюсь выполнить приведенную ниже команду, чтобы вернуть только последнее двоеточие, но она возвращает полную строку. Насколько я понимаю, он должен возвращать только : , а не cat@sampleserver2: . Что я делаю не так? Я также использую версию Perl, которая должна справиться с этим.

cat test.txt | perl -ne 'print if /.+@.+\K:/'
cat@sampleserver2:
% perl -v 
This is perl 5, version 30, subversion 1 (v5.30.1) built for
x86_64-linux-ld

Ответы [ 2 ]

4 голосов
/ 14 июля 2020

Вы можете сказать:

perl -ne 'print $& if /.+@.+\K:/' test.txt

, который выводит:

:
  • Оператор print if CONDITION эквивалентен print $_ if CONDITION и просто печатает строку без изменений при соблюдении УСЛОВИЙ. Вместо этого используйте $&.
  • Второй аргумент cat@sampleserver2: вызовет ошибку: «Не удается открыть cat@sampleserver2 :: Нет такого файла или каталога».
1 голос
/ 14 июля 2020

\K игнорирует часть совпадения , поэтому оно не отображается в $& (или в части строки, которую заменит s///. Но вы выводите $_ , переменная по умолчанию, которую print использует, когда вы не даете ей аргумента.

Я не знаю, почему вы хотите вернуть последнее двоеточие. Если вы знаете, что вы собираетесь выводить только двоеточие, вы не нужны причудливые функции регулярных выражений. Сопоставьте строку, затем выведите известную строку:

 print ':' if /.+\@.+:/

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


Кроме того, ваш однострочный запрос выглядит подозрительно. У вас есть:

cat test.txt | perl -ne 'print if /.+@.+\K:/' cat@sampleserver2:

Этот cat@sampleserver2: является аргументом командной строки и неявный while(<>){...} из переключателя -n попытается открыть файл с таким именем и прочитать его. Возможно, у вас есть файл с таким именем. Это имя файла не является целью для оператора сопоставления, но я подозреваю, что вы думаете, что это .

Но, если у вас есть файл с это имя, почему вы также передаете другой файл? Здесь вам не нужно cat. Это прочитает строки test.txt :

% perl -ne 'print if /.+@.+\K:/' test.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...