grep with regular expression optional value

field 12345 12345
field 12345
field 12345 123456

last fleld (from three) is optional, but if it occures It has to be composed only of nummbers and maximum 5 positions long.

If I use:

grep "^field [0-9]\{5\}"

I get:

field 12345 12345
field 12345
field 12345 123456

But I wont to get just:

field 12345 12345
field 12345

I thought that this will work, but it doesent:

grep "^field [0-9]\{5\} [0-9]\{0,5\}"

try..

grep "^field [0-9]\{5\} [0-9]\{0,5\}$" file

---------- Post updated at 10:20 PM ---------- Previous update was at 10:19 PM ----------

remember grep search matching lines. so you should tell it to stop at a certainpoint

-bash-3.2$ cat file
a
ab
abc
-bash-3.2$ grep ab file
ab
abc
-bash-3.2$ grep ab$ file
ab
-bash-3.2$

Great, thanks this works. But what if this field is not the last one in the row. Like this:

field 12345 12345 a
field 12345 a
field 12345 123456 a

In that case this �guy� dos not work:

grep "^field [0-9]\{5\} [0-9]\{0,5\} [a-z]$" file

what output you want then?

I wont:

field 12345 12345 a
field 12345 a

But with

grep "^field [0-9]\{5\} [0-9]\{0,5\} [a-z]$" file

I get:

field 12345 12345 a

this is quite complex.. i couldnt think of anything beside awk.

awk '{if (length($3) <= 5) {print $0}}' file

I guess in this case, your conditions are:

(i) Print the line if the number of fields is less than 3
(ii) If the 3rd field exists, print the line if it does not consist of any digits. Its length does not matter here.
(iii) If the 3rd field exists, print the line if it consists ONLY of digits and has a length of 5 or less.
(iv) There can be more than 3 fields, and the line will be printed as long as rules (ii) and (iii) are satisfied.

So for the data below, you want to display lines 1,2,4 and 7:

$
$ cat -n data.txt
     1  field 12345 12345 a
     2  field 12345 a
     3  field 12345 123456 a
     4  field 12345
     5  field 12345 12aQ~
     6  field 12345 12aQ~ 123
     7  field 12345 1340 4578 abc AB#xy2
$
$

Perl script:

$
$ perl -ne '@a=split; $f=$a[2]; ($x=$f)=~s/\d//g; ($y=$f)=~s/\D//g;
>           print if ( $#a<2 or
>                      ($#a>=2 and $x eq $f) or
>                      ($#a>=2 and $y eq $f and length($f)<=5)
>                    )' data.txt
field 12345 12345 a
field 12345 a
field 12345
field 12345 1340 4578 abc AB#xy2
$
$

tyler_durden

Thank�s man.
But can�t you do this somehow with grep and reg. expressions? I have checked man for grep and I see speciall characters like "?" could be helpfull, but I don�t know how to used it.

But thanks tyler_durden, your solution in perl does the trick in this case.

try the negation of grep:
$more file1
field 12345 12345
field 12345
field 12345 123456

$grep -v "[0-9]\{6\}" file1
field 12345 12345
field 12345

I got it!

 
cat f

field 12345 12345 a
field 12345 a
field 12345 123456 a
field 12345 12345
 
 
grep "^field [0-9]\{1,5\}\( [0-9]\{1,5\}\|\) [a-z]$" f

field 12345 12345 a
field 12345 a

Thanks everyone for help!

Hi,
I've got a file which different lines. There are an sql sentence in each one. It looks like this:

alter table bla bla
insert into bla bla
select bla bla
alter table

I'd like the output to show the matches in the same order as they are in the original file. I think that could be done with the "or" or using regexp.
That is, something like this:

grep "insert into" || "alter table" archivo

So it would show the line either with "insert into" or "alter table", the first matching line

Maybe this is done with regexp, I havent used them much and cant find the way to solve this.

Any help?
Thanks in advance.

Hello.

Per our forum rules, all posts must be in English.

We do provide translation services for posts from English to a number of languages as a benefit to users. However, posts must be in English.

Please repost in English.

Thank you for your cooperation.

The UNIX and Linux Forums.