Visit Our UNIX and Linux User Community


| help | unix | grep - Can I use grep to return a string with exactly n matches?


 
Thread Tools Search this Thread
Top Forums UNIX for Dummies Questions & Answers | help | unix | grep - Can I use grep to return a string with exactly n matches?
# 1  
Old 10-12-2009
| help | unix | grep - Can I use grep to return a string with exactly n matches?

Hello,

I looking to use grep to return a string with exactly n matches.

I'm building off this:

Code:
 
ls -aLl /bin | grep '^.\{9\}x' | tr -s ' '

Code:
-rwxr-xr-x 1 root root 632816 Nov 25 2008 vi
-rwxr-xr-x 1 root root 632816 Nov 25 2008 view
-rwxr-xr-x 1 root root 16008 May 25 2008 ypdomainname
-rwxr-xr-x 3 root root 62864 May 28 2008 zcat
-rwxr-xr-x 1 root root 594848 Jan 7 2007 zsh

Which prints a list of files in long format that are have an 'x' in the last file permissions position, then remove spaces between characters so that there is at most one. I now want to print just the file name. The following code does exactly that:

Code:
ls -aLl /bin | grep '^.\{9\}x' | tr -s ' ' | cut -d' ' -f9

Code:
vi
view
ypdomainname
zcat
zsh

What I want to see if I can do is use grep instead of cut.
I figure I would need grep to be able to match a pattern exactly n times then match .*/n$.
I would want to match [[:blank:]] 8 times then match any number of characters followed by an end of line character at the end of the string.

Code:
ls -aLl /bin | grep '^.\{9\}x' | tr -s ' ' | grep 'match[[:blank:]] 8 sequential or non-sequential times then .*/n$'

Any ideas if I can do this with grep and the power of regular expression?
I tried various expressions on the built in dictionary to see if I could return words with say exactly 4 'a' anywhere in the word without successs.
# 2  
Old 10-13-2009
This should work:
Code:
grep -o "[^ ]*$"

It is probably better to do a pattern match anyway instead of a column number match, since the ls -l listing may take up more or fewer fields, depending on your locale.

Or use find:
Code:
find -L /bin/* -maxdepth 1 -perm /001

If you want to filter out the leading path you can use sed:
Code:
find -L /bin/* -maxdepth 1 -perm /001|sed 's|.*/||'

or a find option:
Code:
find -L /bin/* -maxdepth 1 -perm /001 -printf "%P\n"

or if you only want the files
Code:
find -L /bin -maxdepth 1 -type f -perm /001 -printf "%P\n"


Last edited by Scrutinizer; 10-13-2009 at 02:35 AM..
# 3  
Old 10-13-2009
The thread id changed because I merged this thread with another by mistake, sorry.
You may need to re-subscribe to get notifications.
# 4  
Old 10-13-2009
Ok, cool.

grep -o prints just the matching sting on its own line.
[^ ]*$ matches any number of non-space, non-tab characters in a sequence that are at the of a line.

So, this seems good for grabbing text at the end of any line.

However, I'm still trying to match lines that can exactly n matches. MY current thoughts are find a line with only two 'x':
Code:
ls -aLl -R /bin | grep -o 'x.*x[^x]*'

x.*x[^x]* = find a 'x', followed by any number of any character, find a 'x', followed by any number of characters not 'x'
This just list highlights the entire line.

Code:
ls -aLl -R /bin | grep 'x'

This highlights each 'x' in a line without highlighting any other characters. Match any number of 'x'.

Code:
ls -aLl -R /bin | grep 'x\+'

This does the same as the above. Match any number of 'x'.

Code:
ls -aLl -R /bin | grep 'x\{n\}'

n = 1, matches like the above two examples. Match any number of 'x'.
n = 2, matches only when 'x' in a sequence of two. Sequence of four match because 'xxxx' is 'xx' 'xx', 'xxx' is only matched 'xx'. (I think).

Code:
ls -aLl -R /bin | grep 'x.*x'

This highlights all the characters between the first 'x' and last 'x'. Match at least two 'x'.

Code:
ls -aLl -R /bin | grep 'x.*x\{1\}'

This, appears to match the same sections in a line as the above code. Match at least two 'x'.

Code:
ls -aLl -R /bin | grep  '[^x]*'

This only highlights the line up until the first 'x'. Match all characters up until the first 'x'.

I think the issue may relate to the "greedy" regex engine, so to control it is the issue.
I think I may need to specify hard limit with \{1\}.
Also I'm not sure if I can use look ahead/behind/around or conidtional with grep's regular expressions, but these commands may solve the problem as well. x\(?!x\)
I may possibly need to use \? before the "." for cases that are xxx and I want to match exactly two 'x'.

Side question:
[^ ] == [^[:blank:]] == horizontal space, tab == \t
Horizontal single space == " " but it has no numerical representation for an amount like " " is the literal equivalent to " "?

Last edited by MykC; 10-13-2009 at 12:18 PM..
# 5  
Old 10-13-2009
you could just do:

Code:
 ls -aLl /bin | awk '/x /{print $9}'

which should be close ;-)
# 6  
Old 10-13-2009
Thanks, that definitely does it.

I haven't gotten around to awk and sed so I'm still unsure on how they operate exactly. This is mainly an exercise for myself to understand the basics on regular expressions though and limitations of some of the simplier programs that take regular expressions.

So, I'm still trying to use grep and my short term goal is to return lines from:

Code:
 
ls -aLl -R /bin

That contain exactly two 'x' characters. No more, no less. Preferably using grep.

Last edited by MykC; 10-13-2009 at 12:12 PM..
# 7  
Old 10-13-2009
..contain exactly two 'x' characters. No more, no less. Preferably using grep...

one way:

Code:
#  ls -aLl -R /bin | grep "^[^x]*x[^x]*x[^x]*$"

HTH
 

Previous Thread | Next Thread
Test Your Knowledge in Computers #26
Difficulty: Easy
IPv6 addresses are 256 bits in length.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Replace string of a file with a string of another file for matches using grep,sed,awk

I have a file comp.pkglist which mention package version and release . In 'version change' and 'release change' line there are two versions 'old' and 'new' Version Change: --> Release Change: --> cat comp.pkglist Package list: nss-util-devel-3.28.4-1.el6_9.x86_64 Version Change: 3.28.4 -->... (1 Reply)
Discussion started by: Paras Pandey
1 Replies

2. Shell Programming and Scripting

Grep -w not printing exact matches

Dear All, Here is my input TAACGCACTTGCGGCCCCGGGATAAAAAAAAAAAAAAAAAAAAATGGATT NAGAGGGACGGCCGGGGGCATAAAAAAAAAAAAAAAAAAAAAGGGATTTC NGGGTTTTAAGCAGGAGGTGTCAAAAAAAAAAAAAAAAAAAAAGGGATTT NTGGAACCTGGCGCTAGACCAAAAAAAAAAAAAAAAAAAATGGATTTTTG ATACTTACCTGGCAGGGGAGATACCATGATCAATAAAAAAAAAAAAAAAA... (3 Replies)
Discussion started by: jacobs.smith
3 Replies

3. Shell Programming and Scripting

grep - match files containing minimum number of pattern matches

I want to search a bunch of files and list only those containing a minimum number of pattern matches. So if I want to identify files containing 3 (or more) instances of the pattern "said:" and I have file1 that contains the lines: He said: She said: and file2 that contains the lines: He... (3 Replies)
Discussion started by: stumpyuk
3 Replies

4. UNIX for Dummies Questions & Answers

grep multiple matches

i dun seems to be able to grep the arguments i want. eg. book.txt with description inside. ABC:efg:5:6 HHH:JJJ:6:7 i want the user to input the book title and author they want. so when the user enters book title ABC and book author efg, they print out exact match of ABC:efg:5:6. Caps do... (2 Replies)
Discussion started by: santonio
2 Replies

5. Shell Programming and Scripting

Using grep returns partial matches, I need to get an exact match or nothing

I’m trying to modify someone perl script to fix a bug. The piece of code checks that the zone name you want to add is unique. However, when the code runs, it finds a partial match using grep, and decides it already exists, so the “create” command exits. $cstatus = `${ZADM} list -vic | grep... (3 Replies)
Discussion started by: TKD
3 Replies

6. Shell Programming and Scripting

find/grep returns no matches

Hi all! I've faced with very unintelligible error using find/grep like this: root@v29221:~# find /var/www/igor/data/www/lestnitsa.ru | grep u28507I get nothing as a result, but: root@v29221:~# grep u28507 /var/www/igor/data/www/lestnitsa.ru/_var.inc $db_name = 'u28507';... (2 Replies)
Discussion started by: ulrith
2 Replies

7. UNIX for Dummies Questions & Answers

| help | unix | grep (GNU grep) 2.5.1 | advanced regex syntax

Hello, I'm working on unix with grep (GNU grep) 2.5.1. I'm going through some of the newer regex syntax using Regular Expression Reference - Advanced Syntax a guide. ls -aLl /bin | grep "\(x\)" Which works, just highlights 'x' where ever, when ever. I'm trying to to get (?:) to work but... (4 Replies)
Discussion started by: MykC
4 Replies

8. Shell Programming and Scripting

Grep regex matches, groups

Hello, I am searching all over the place for this, just not finding anything solid :( I want to do be able to access the groups that are matched with grep (either with extended regex, or perl compatible regex). For instance: echo "abcd" | egrep "a(b(c(d)))" Of course this returns... (1 Reply)
Discussion started by: Rhije
1 Replies

9. UNIX for Dummies Questions & Answers

Any way to grep a string in directories and return the result with diskusage aswell?

What Im basically trying to do is this: I have a small script that can grep any parameter entered into a search string, then print to the screen the name of each file the parameter appears in as well as the file path, ie the directory. The code Im using just for this is.... Directory... (3 Replies)
Discussion started by: Eddeh
3 Replies

10. Shell Programming and Scripting

Appending Text To Each Line That Matches Grep

I'm currently digging for a way to append a line to a text file where each line begins with the word "setmqaut". This is a continuation of my IBM MQSeries backup script I'm working on to make my life a little easier. What I would like to do is have each line that looks like this: setmqaut -m... (4 Replies)
Discussion started by: sysera
4 Replies

Featured Tech Videos