Search code examples
bashsplit

Split strings by a certain delimiter and extract the output for further processing


I have a list of directory names (each in one line) that consist of the names of rubygems and their version.

I want to split them at the last hyphen in the string.

The folder-name string consists

  • of the name of the gem
  • and as the second part of a version number

How can one extract both for further processing and keep a relationship between the gem-name and the version-numbers established?

Given the list that find returns

find . -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"

My approach would have been nested arrays, like this

declare -A my_gems
my_gems[gem_name]=()
# append version numbers to the right hand side array

I need to further process it in the context of parsing user arguments to a script which contains of a gem_name and a list of versions.


Solution

  • A while read loop approach should be something like.

    #!/usr/bin/env bash
    
    declare -A my_gems
    find . -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$" | {
      while IFS= read -r line; do
        line=${line#*./}
        my_gems[${line%-*}]=${line##*-}
      done
    }
    
    declare -p my_gems
    

    As suggested by @oguz using a Process Substitution.

    #!/usr/bin/env bash
    
    declare -A my_gems
    
    while IFS= read -r line; do
      line=${line#*./}
      my_gems[${line%-*}]=${line##*-}
    done < <(find . -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$")
    
    declare -p my_gems