ritter
ritter

Reputation: 7699

get part of a string which contains given substring

In bash I have a string and would like to get the part (separator being white space characters) that contains a certain substring. Like I have

LIST="some string with a substring you want to match"

and my substring is "ubst". I'd like to get the string "substring" returned. (In case of multiple matches it should return the first substring that matches.)

The parts of the string are compiler flags. So they can contain special characters (but no white space).

Upvotes: 3

Views: 147

Answers (6)

Corubba
Corubba

Reputation: 2243

Using only grep with the -o and head:

echo "${LIST}" | grep -oe '[^ ]*ubst[^ ]*' | head -n 1

Upvotes: 2

anubhava
anubhava

Reputation: 784898

Using awk you can do this:

str="some string with a substring you want to match"
awk -v s='ubst' -v RS=' ' '$0 ~ s' <<< "$str"
substring
  • -v RS=' ' will set record separator as space thus breaking each space separated word into individual record.
  • $0 ~ s will return the word when word matched your given search term

PS: If you want to print only the first match use:

awk -v s='ubst' -v RS=' ' '$0 ~ s{print; exit}' <<< "$str"

Just for academic exercise if one wants single grep then use this PCRE regex:

grep -oP '^(?:(?!\w*ubst).)*\K\w*ubst\w*' <<< "$str"

Upvotes: 3

user2350426
user2350426

Reputation:

awk -v RS='[ \t]'  '!/ubst/{next}1'

Description:

As you stated that

(separator being white space characters)

The string could be broken into records by that, then just match the record that contain ubst.

LIST="some string with a substring you want to match"

echo "$LIST" | awk -v RS='[[:blank:]]'  '!/ubst/{next}1'

Well, really, if the record does not match ubst goes to the next record.
Any record that is matched falls to the default 1 which means print.

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84521

There is always the built-in regex operator for the [[ conditional:

str="some string with a substring you want to match"
a=( $(echo "$str") )
for i in "${a[@]}"; do
    [[ "$i" =~ "ubst" ]] && printf "%s\n" "$i"
done

You can also use the POSIX compliant expr string : regex expression as well:

[ $(expr "$i" : ".*ubst.*") -gt 0 ] && printf "%s\n" "$i"

Upvotes: 1

Rany Albeg Wein
Rany Albeg Wein

Reputation: 3474

#!/bin/bash

line="some string with a substring you want to match"

print_inarray ()
{ 
    local n=$1 h
    shift
    for h in "$@";do
        if [[ $h = *"$n"* ]]; then
            printf '%s\n' "$h"
            return
        fi
    done
    return 1
}

# Read the line into an array.
read -ra arr <<< "$line"
# Find a substring of a word in array and print the complete word.
print_inarray "ubst" "${arr[@]}"

Upvotes: 1

Walter A
Walter A

Reputation: 19982

Using tr and grep

echo "${LIST}" | tr " " "\n" | grep -m1 ubst

Upvotes: 1

Related Questions