2013-02-17 2 views
2

У меня есть файл, который имеет строки в нем, которые выглядят подобно тому, как следуетRegex - Одинаковый произвольное количество чисел

data 
datalater 
983290842 
Data387428later 
datafhj893724897290384later 
4329804928later 

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

^[D,d]ata[0-9]*later$ 

Однако выход включает в себя все линии данных. Полагаю, я мог бы вывести выход и grep -v datalater, но я чувствую, что одно выражение должно делать трюк.

ответ

2

Использовать + вместо *.

+ соответствует хотя бы одному или нескольким из предыдущих.
* соответствует нулю или больше.

^[Dd]ata[0-9]+later$ 

В Grep вам нужно, чтобы избежать +, и мы можем использовать \d который является классом символов и соответствует одной цифре.

^[Dd]ata\d\+later$ 

В вас примере файл вы также строку:

datafhj893724897290384later 

Это в настоящее время не будет сравниваться из-за там быть буквами, между данными и цифрами. Мы можем исправить это, добавив [^0-9]*, чтобы соответствовать чему-либо после данных до цифр.

Наша последняя команда будет:

grep '^[Dd]ata[^0-9]*\d\+later$' filename 
+0

При использовании этого выражения, или @Eric, я не получаю никаких результатов на выходе. Вот что я использую: grep^[D, d] ata [0-9] + later $ filename – hdub

+0

Не понял, что вы используете grep, будет обновляться. –

+0

Еще не кубик с этим даже в качестве копии/вставки. – hdub

1

Вы должны поставить «+» (что означает один или несколько) вместо «*» (что означает ноль, один или несколько

+0

oOps, Том ответил, когда я писал ответ между несколькими вещами, он получил его! – Fafhrd

2

Вы» повторное соответствие ноль или более цифр с * классификатором. Попробуйте

^[Dd]ata\d+later$ 

вместо этого. Вы также найти запятые в начале строки (например, «ata1234later»). А \ d ярлык для нахождения любой цифры характер. Я тоже изменил их.

+0

Я бы хотел, чтобы это показало результат, но не дает никаких результатов. Смотрите мой ответ на @Tom – hdub

0

Использование Cygwin, приведенные выше команды не работают. Мне пришлось изменить приведенные выше команды, чтобы получить желаемые результаты.

$ cat > file.txt <<EOL 
> data 
> datalater 
> 983290842 
> Data387428later 
> datafhj893724897290384later 
> 4329804928later 
> EOL 

Я всегда хотел, чтобы убедиться, что мой файл имеет то, что я ожидаю, что это есть:

$ cat file.txt 
data 
datalater 
983290842 
Data387428later 
datafhj893724897290384later 
4329804928later 

$ 

мне нужно запустить выражения Perl-стиль с -P флагом. Это означало, что я не мог использовать [^0-9]+, чья необходимость @Tom_Cammann метко указала. Вместо этого я использовал .*, который соответствует любой последовательности символов, не соответствующих следующей части шаблона. Вот моя команда и вывод.

$ grep -P '^[Dd]ata.*\d+later$' file.txt 
Data387428later 
datafhj893724897290384later 

$ 

Я хотел бы дать лучшее объяснение того, почему необходимы Perl выражения, но я просто знаю, что Cygwin-х grep работает немного по-другому.

System Info

$ uname -a 
CYGWIN_NT-10.0 A-1052207 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin 

Мои результаты от предыдущих ответов

$ grep '^[Dd]ata[^0-9]*\d\+later$' file2.txt 

$ grep '^[Dd]ata\d+later$' file2.txt 

$ grep -P '^[Dd]ata[^0-9]*\d\+later$' file2.txt 

$ grep -P '^[Dd]ata\d+later$' file2.txt 
Data387428later 

$ 
Смежные вопросы