0

I am looking how to bash script a hostname and grab everything in between numbers into a var. For example, let's say the hostname is abcd1efghij12kl. How do return just efghij?

The number of letters before the first number varies and the number of letters after the second number can vary and inbetween.

Also to first number could be 1 or 2 digits and same for the second set of numbers. I am looking to get only the letters in between. When I try IFS i can't seem to get anywhere. Thanks

3 Answers 3

2

Here's 2 ways to do it with bash:

hostname=abcd1efghij12kl

# using a subshell so the IFS and options don't affect your running shell
(IFS=0123456798; set -f; set -- $hostname; echo "$2")
# => efghij

# using a regular expression and the BASH_REMATCH array
if [[ $hostname =~ [[:digit:]]([^[:digit:]]+)[[:digit:]] ]]; then
  echo "${BASH_REMATCH[1]}"
fi
# => efghij

The key is that IFS is a "set" of characters, not a pattern. If you tried IFS="[0-9]", then bash will try to split using the 5 characters [, 0, -, 9, ]

Sign up to request clarification or add additional context in comments.

5 Comments

How do i get the hostname as a var without doing it manually. This works when i set the hostname manually but not when i do something like HOSTNAME='hostname' or HOSTNAME=$(cat /proc/sys/kernel/hostname)
The Command Substitution syntax is hostname=$(hostname)
Get out of the habit of using ALLCAPS variable names, leave those as reserved by the shell. One day you'll write PATH=something and then wonder why your script is broken.
when I do it that way i get nothing in return on (IFS=0123456798; set -f; set -- $hostname; echo "$2") I only get it if hostname= is set manually
nvm, got it. Thanks
1

You can use parameter expansions in bash (extended globbing needed):

#! /bin/bash
shopt -s extglob                                   # Turn on extended globbing
for hostname in abcd1efghij12kl abcd12efghij12kl abcd12efghij2kl abcd1efghij1kl ; do
    between_digits=${hostname##+([^0-9])+([0-9])}  # Remove everything up to the first number
    between_digits=${between_digits%%[0-9]*}       # Remove everything starting from the last number
    echo "$between_digits"
done

Comments

0

Using sed:

echo "abcd1efghij12kl"| sed -E 's/.*[[:digit:]]([^[:digit:]]+)[[:digit:]].*/\1/g'

Output:

efghij

1 Comment

You have to remove one [ in ([^[[:digit:]]+), resulting in ([^[:digit:]]+). Teststring: abcd1ef[ghij12kl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.