Использование подстановочного знака в начале выражения grep влияет на результат

, если вы хотите быть по-настоящему дерзким, вы всегда можете преобразовать даты, основанные на эпохе 1970-01-01 00:00:00 УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ.

#added to fix DD/MM/YY format
input1=`echo $1 | awk -F "/" '{print $2"/"$1"/"$3}'`
input2=`echo $2 | awk -F "/" '{print $2"/"$1"/"$3}'`

date1=`date +%s --date="$input1"`
date2=`date +%s --date="$input2"`
if [[ "$date1" -lt "$date2" ]]; then
    echo "$1 earlier than $2"
else
    echo "$1 not earlier than $2"
fi
4
03.05.2018, 15:14
1 ответ

grepшаблоны являются регулярными выражениями (также известными как регулярное выражение, регулярное выражение, RE ), базовые регулярные выражения (BRE ), кроме одного из -E/ -F/ -P/ -K/ -Xвариант (используются только первые два из которых являются стандартными ).

*— это оператор регулярного выражения, который соответствует 0 или более предшествующих атомов . Например, d*соответствует 0 или более dс. В BRE, когда в начале шаблона или после операторов регулярного выражения ^или \(он соответствует буквальному *только (, он также воспринимается буквально внутри [...]выражений в квадратных скобках ).

Таким образом, grep '*README.md*'соответствует строкам, которые содержат литерал *, за которым следует README, за которым следует любой одиночный символ (оператор регулярного выражения .), за которым следует m, за которым следует любое количество dс. Поскольку любое число включает 0, это функционально эквивалентно grep '*README.m'(, что не имеет значения, какие строки сопоставляются, только то, что может сопоставляться в строке (, что будет отображаться с --colorвариант GNU grep, например )).

Например, он будет соответствовать этим двум строкам:

*README mike
^^^^^^^^^
DONT***README-mddd
      ^^^^^^^^^^^^

(^показывает, что в строке соответствует регулярному выражению, что вы могли видеть с помощью--color)

Здесь,кажется, вы путаете регулярные выражения с шаблонами подстановочных знаков оболочки. Оператор подстановки *, который соответствует 0 или более символам, может быть записан .*в регулярных выражениях. Но делать:

grep '.*README\.md.*'

снова будет таким же, как:

grep 'README\.md'

Поскольку grepищет совпадение внутри строки, а не находит строки, точно соответствующие шаблону (, для которого вам нужен-x).

С ast -открытым grep, который также является ksh93встроенным grep(не всегда встроенным -по умолчанию, и вам нужно включить его, поставив /opt/ast/binвпереди из $PATH), вы можете использовать опцию -Kдля grep, чтобы использовать подстановочные знаки оболочки (расширенные ksh93 ). Итак, с этой реализацией grepвы можете сделать:

grep -K 'README.md'

или

grep -xK '*README.md*'

для соответствия строкам, содержащим README.md.

В этой же реализации сопоставление с подстановочными знаками также может быть включено в расширенных (-E), , расширенных(-X)или perl -, например(-P)регулярных выражениях с оператором (?K)\(?K\). ] в основных регулярных выражениях, что на самом деле нарушает соответствие POSIX, поэтому я бы не стал полагаться на него, так как он может быть удален в будущей версии ). Так что вы можете сделать:

grep -xE '(?K)*README.md*'

там.

С любой современной grepреализацией вы также можете:

grep -F README.md

Для фиксированного -поиска строки (, где .выше соответствует литерал .вместо любого символа ).

22
27.01.2020, 20:44

Теги

Похожие вопросы