LINUX.ORG.RU

помогите с egrep

 ,


0

2

нужно найти строчки типа

3242-24-85455
3-2-42-24-85-455

т.е такие, что содержат 12 цифр и разделены минусами, но главное чтобы среди этих 12 цифр был хотя бы один минус. Придумал так:

egrep '[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]' ./*.txt
Но получается, что находит и строки без минусов. Помогите пожалуйста)



Последнее исправление: zagruzkaaa (всего исправлений: 1)

Бей перлом, фредди!

echo -e "123-456789012\n123456789012" | perl -ne '$digit_count = $_ =~ tr/[0-9]//; $is_minus=index($_, "-") != -1; print "$_" if $digit_count==12 and $is_minus'
123-456789012

$- — текущая строка stdin, включая \n.

anonymous
()
grep '-'  ./*.txt | egrep '[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]-{0,1}[0-9]'
Smola
()
Ответ на: комментарий от thesis

Как предлагаешь сделать лучше?
Кроме как поменять местами первые два паттерна, ничего ее могу придумать.

Smola
()
Ответ на: комментарий от zagruzkaaa

То опаньки. Если надо непременно в одну команду, то заюзай сед:

[lc40222@melpulp01 ~]$ echo "123412341234" | sed -n -E -e '/\-/ !d' -e '/[[:digit:]][[:digit:]\-]{10}[[:digit:]]/ p'
[lc40222@melpulp01 ~]$ echo "123412-341234" | sed -n -E -e '/\-/ !d' -e '/[[:digit:]][[:digit:]\-]{10}[[:digit:]]/ p'
123412-341234
[lc40222@melpulp01 ~]$

Чтобы оно выводило имена файлов тебе придется склепать скриптик.

И регекс у тебя адовый получился, конечно.

alex_the_v ★★★
()
Ответ на: комментарий от thesis

Точно?

[smola@HP250 tst]$ grep -P '\d(?!\d{11})((\d\d)|(\d\-(?!\-))|((?<!\-)\-\d)){5}\d' *.txt
1.txt:12345678901-2
1.txt:1234567890-1-2
1.txt:12345-67890-1-2
1.txt:12345-67890-1-2ee
1.txt:1112345-67890-1-2ee
1.txt:1112345-67890-1-2
2.txt:12345-67890-1-2
2.txt:12345-67-890-1-2
3.txt:1234-56890-12

[smola@HP250 tst]$ grep '' *.txt
1.txt:12345678901-2
1.txt:1234567890-1-2
1.txt:12345-67890-1-2
1.txt:12345-67890-1-2ee
1.txt:1112345-67890-1-2ee
1.txt:1112345-67890-1-2
2.txt:12345-67890-1-2
2.txt:12345-67-890-1-2
2.txt:123456789012
3.txt:123456789012
3.txt:1234-56890-12

Smola
()
Ответ на: комментарий от alex_the_v

У меня все норм:

$ grep -hxE '([0-9]-{0,1}){11}[0-9]' *.txt | grep "-" | grep -xf - *.txt
1.txt:12345678901-2
1.txt:1234567890-1-2
1.txt:12345-67890-1-2
2.txt:12345-67890-1-2
2.txt:12345-67-890-1-2

Smola
()
Ответ на: комментарий от thesis

Да чего там экспериментал

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

alex_the_v ★★★
()
Ответ на: комментарий от thesis

У меня, кстати, тоже не пашет:

[lc40222@melpulp01 ~]$ echo "12341234-1234adsf" | grep -P '\d(?!\d{11})((\d\d)|(\d\-(?!\-))|((?<!\-)\-\d)){5}\d'
12341234-1234adsf
[lc40222@melpulp01 ~]$ grep -V
grep (GNU grep) 2.20

alex_the_v ★★★
()
Ответ на: комментарий от Smola

У меня, кстати, еще и регексп косячный, матчит 10 цифр или минусов. Твой правильней.

alex_the_v ★★★
()
Ответ на: комментарий от alex_the_v

Прикольно. УМВР. А что за дистр?
ЗЫ: напрашивается вывод «греп крив, регексп крут».

Если кому не лениво, прогоните перлом:

perl  -nle 'print "$&" if /\d(?!\d{11})((\d\d)|(\d\-(?!\-))|((?<!\-)\-\d)){5}\d/' rexptest.txt
# cast Smola

thesis ★★★★★
()
Последнее исправление: thesis (всего исправлений: 2)

OMG! KISS

egrep '[0-9-]{13,23}'

Т.е. у нас любая комбинация с минимум 12 цифр и даш и до 12 цифр и 11 дашей и всё что посередине. Остальное можно вычистить во втором проходе.

PS: Some people, when confronted with a problem, think «I know, I'll use regular expressions.» Now they have two problems.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 4)
Ответ на: комментарий от thesis

Обрезает строки:

[smola@HP250 tst]$ perl  -nle 'print "$&" if /\d(?!\d{11})((\d\d)|(\d\-(?!\-))|((?<!\-)\-\d)){5}\d/' all.txt 
2345678901-2
1234567890-1
2345-67890-1
2345-67890-1
1112345-6789
1112345-6789
2345-67890-1
12345-67-890
1234-56890-1
[smola@HP250 tst]$ cat  all.txt
12345678901-2
1234567890-1-2
12345-67890-1-2
12345-67890-1-2ee
1112345-67890-1-2ee
1112345-67890-1-2
12345-67890-1-2
12345-67-890-1-2
123456789012
123456789012
1234-56890-12

Smola
()
Последнее исправление: Smola (всего исправлений: 1)
Ответ на: комментарий от thesis
[lc40222@melpulp01 ~]$ cat /etc/redhat-release
CentOS release 6.7 (Final)
[lc40222@melpulp01 ~]$ echo -ne "1234-1234-1234\n3216-6547-9874sdfasdfa\n" >rexptest.txt
[lc40222@melpulp01 ~]$ perl  -nle 'print "$&" if /\d(?!\d{11})((\d\d)|(\d\-(?!\-))|((?<!\-)\-\d)){5}\d/' rexptest.txt
1234-1234-12
3216-6547-98

Я ж тебе говорил, что -P не рулит =)

alex_the_v ★★★
()
Ответ на: комментарий от beastie

Правильно говорят: простота хуже воровства. На втором проходе вычистить мы тут все такие умные. Ты в один регексп попробуй, вон Тезис хоть и владеет кунг фу, а тоже лажанул немного.

Мистер загрузкааааа, маза, даже не ожидал такого живого интереса к своей проблеме =)

alex_the_v ★★★
()
Ответ на: комментарий от Smola

Потому что «print $&» это вывод найденной подстроки.

thesis ★★★★★
()
grep -P "\d*(-\d*){1,5}$"
anonymous
()
Ответ на: комментарий от Smola

Твоя команда получается игнорирует строки типа

fdfdfd123-456789012asas
т.е такие строки где есть текст перед и после цифрами. А как сделать чтобы не игнорировал?

zagruzkaaa
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.