Как Perl обрабатывает шаблон с разными цитатами?
Как указывает https://perldoc.perl.org/perlrun.html,
Опция -F определяет шаблон для разделения на -a. Шаблон может быть заключен в символы //, "" или ", иначе он будет заключен в одинарные кавычки. Вы не можете использовать буквенные пробелы или NUL-символы в шаблоне.
Я попробовал ниже команды для текста, но результат полностью тот же.
Так в чем же разница этих цитат в приведенном ниже примере?
$ perl -aF"\|" -lne 'print $F[0]' input
Time
2018-01-11 00:00:00
2018-01-11 00:15:00
$ perl -aF'\|' -lne 'print $F[0]' input
Time
2018-01-11 00:00:00
2018-01-11 00:15:00
$ perl -aF/\|/ -lne 'print $F[0]' input
T
2
2
$ perl -aF"|" -lne 'print $F[0]' input
T
2
2
$ perl -aF'|' -lne 'print $F[0]' input
T
2
2
$ perl -aF/|/ -lne 'print $F[0]' input
bash: /: Is a directory
1 ответ
Есть три уровня интерпретации, которые вы должны рассмотреть.
Первый слой - это оболочка. Второй уровень - это синтаксис perl для строковых / регулярных выражений. Третий уровень - это синтаксис регулярных выражений Perl.
Давайте рассмотрим ваши примеры, один за другим:
"\|"
а также '\|'
оба передают двухсимвольную строку (\|
) в Perl ("
а также '
интерпретируются оболочкой). Это первый слой.
\|
не заключен в кавычки, поэтому Perl добавляет ''
вокруг него, образуя нить '\|'
(как в split '\|', $_
). Строки в Perl, заключенные в одинарные кавычки, специально не обрабатывают обратную косую черту (если за ней не следует \
или же '
), поэтому Perl думает, что это все еще двухсимвольная строка, \|
, Это второй слой.
split
интерпретирует свой первый аргумент как регулярное выражение. \
имеет особое значение в регулярном выражении: экранирует следующий символ. Таким образом, регулярное выражение \|
соответствует одному |
(символ конвейера), и именно поэтому этот код разбивает свой ввод на |
, Это третий слой.
/\|/
передает трехсимвольную строку /|/
на Perl (\
интерпретируется оболочкой). Это первый слой.
/|/
выглядит как-то (|
) окружен //
так что perl ничего не добавляет (split /|/, $_
). Это анализируется как регулярное выражение, и здесь ничего особенного не происходит: |
, Это второй слой.
|
имеет особое значение в регулярном выражении (если не \
): A|B
означает "соответствовать либо A, либо B". В этом случае и A, и B пусты, совпадая с пустой строкой. Разделение на шаблон, который соответствует пустой строке, приводит к списку всех символов во входной строке (фактически, входная строка разбивается везде (на каждой границе символа)). Это третий слой.
"|"
а также '|'
оба передают односимвольную строку (|
) в Perl ("
а также '
интерпретируются оболочкой).
|
не заключен в кавычки, поэтому Perl добавляет ''
вокруг него, образуя нить '|'
(как в split '|', $_
). Это простая односимвольная строка (до сих пор просто |
). Это второй слой.
split
интерпретирует свой первый аргумент как регулярное выражение и, как в предыдущем случае, |
имеет специальное значение ("или"), в результате чего получается список односимвольных элементов. Это третий слой.
|
(вне кавычек и не экранируется \
) - это специальный символ в оболочке: он создает конвейер.
perl -aF/|/ -lne 'print $F[0]' input
такой же как
perl -aF/ | / -lne 'print $F[0]' input
а значит: беги perl -aF/
и направить свой вывод в команду / -lne 'print $F[0]' input
, Это вызывает ошибку, потому что /
не является действительной программой, это каталог.