Reputation: 42277
I have sample data like "(stuff/thing)" and I'm trying to extract "thing".
I'm doing this in the terminal on OSX and I can't quite seem to get this right.
Here's the last broken attempt
echo '(stuff/thing)' | sed -n 's/\((.*)\)/\1/p'
Upvotes: 3
Views: 12283
Reputation: 289775
I would say:
$ echo '(stuff/thing)' | sed -n 's@.*/\([^)]*\))@\1@p'
thing
I start saying:
$ echo '(stuff/thing)' | sed -n 's@.*/@@p'
thing)
Note I use @
as sed delimiter for better readability.
Then, I want to get rid of what comes from the )
. For this, we have to capture the block with \([^)]*\))
and print it back with \1
.
So all together this is doing:
# print the captured group
# ^^
# |
.*/\([^)]*\))@\1
# ^^^| ^^^^^ |
# | | ------|---- all but )
# | | |
# | ^^ ^^
# | capture group
# |
# everything up to a /
Upvotes: 12
Reputation: 438073
To provide an awk
alternative to fedorqui's helpful answer:
awk
makes it easy to parse lines into fields based on separators:
$ echo '(stuff/thing)' | awk -F'[()/]' '{print $3}'
thing
-F[()/]
specifies that any of the characters (
)
/
should serve as a field separator when breaking each input line into fields.$3
refers to the 3rd field (thing
is the 3rd field, because the line starts with a field separator, which implies that field 1 ($1
) is the empty string before it).As for why your sed
command didn't work:
Since you're not using -E
, you must use basic regexes (BREs), where, counter-intuitively, parentheses must be escaped to be special - you have it the other way around.
The main problem, however, is that in order to output only part of the line, you must match ALL of it, and replace it with the part of interest.
With a BRE, that would be:
echo '(stuff/thing)' | sed -n 's/^.*\/\(.*\))$/\1/p'
With an ERE (extended regex), it would be:
echo '(stuff/thing)' | sed -En 's/^.*\/(.*)\)$/\1/p'`
Also note that both commands work as-is with GNU sed
, so the problem is not Mac-specific (but note that the -E
option to activate EREs is an alias there for the better-known -r
).
That said, regex dialects do differ across implementations; GNU sed
generally supports extensions to the POSIX-mandated BREs and EREs.
Upvotes: 4
Reputation: 207465
I would do it in 2 easy parts - remove everything up to and including the slash and then everything from the closing parenthesis onwards:
echo '(stuff/thing)' | sed -e 's/.*\///' -e 's/).*//'
Upvotes: 1