Manny Adumbire
Manny Adumbire

Reputation: 386

Can I perform a 'non-global' grep and capture only the first match found for each line of input?

I understand that what I'm asking can be accomplished using awk or sed, I'm asking here how to do this using GREP.

Given the following input:

.bash_profile
.config/ranger/bookmarks
.oh-my-zsh/README.md

I want to use GREP to get:

.bash_profile
.config/
.oh-my-zsh/

Currently I'm trying

grep -Po '([^/]*[/]?){1}'

Which results in output:

.bash_profile
.config/
ranger/
bookmarks
.oh-my-zsh/
README.md

Is there some simple way to use GREP to only get the first matched string on each line?

Upvotes: 2

Views: 244

Answers (3)

tripleee
tripleee

Reputation: 189317

The -o option says to print every substring which matches your pattern, instead of printing each matching line. Your current pattern matches every string which doesn't contain slashes (optionally including a trailing slash); but it's easy to switch to one which only matches this pattern at the beginning of a line.

grep -o '^[^/]*' file

Notice the addition of the ^ beginning of line anchor, and the omission of the -P option (which you were not really using anyway) as well as the silly beginner error {1}.

(I should add that plain grep doesn't support parentheses or repetitions; grep -E would support these constructs just fine, of you could switch to toe POSIX BRE variation which requires a backslash to use round or curly parentheses as metacharacters. You can probably ignore these details and just use grep -E everywhere unless you really need the features of grep -P, though also be aware that -P is not portable.)

Upvotes: 0

dibery
dibery

Reputation: 3460

I think you can grep non / letters like:

grep -Eo '^[^/]+'

On another SO site there is another similar question with solution.

Upvotes: 2

chepner
chepner

Reputation: 530930

You don't need grep for this at all.

cut -d / -f 1

Upvotes: 2

Related Questions