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

User123
  • 1,498
  • 2
  • 12
  • 26
Tom Donnly
  • 19
  • 5

3 Answers3

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, ]

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 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) – Tom Donnly Sep 07 '21 at 15:44
  • The [Command Substitution](https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution) syntax is `hostname=$(hostname)` – glenn jackman Sep 07 '21 at 16:40
  • 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](https://stackoverflow.com/q/27555060/7552) your [script is broken](https://stackoverflow.com/q/28310594/7552). – glenn jackman Sep 07 '21 at 16:40
  • 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 – Tom Donnly Sep 07 '21 at 18:31
  • nvm, got it. Thanks – Tom Donnly Sep 07 '21 at 19:52
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
choroba
  • 231,213
  • 25
  • 204
  • 289
0

Using sed:

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

Output:

efghij
User123
  • 1,498
  • 2
  • 12
  • 26
  • 1
    You have to remove one `[` in `([^[[:digit:]]+)`, resulting in `([^[:digit:]]+)`. Teststring: `abcd1ef[ghij12kl`. – Walter A Sep 07 '21 at 18:20