skip to Main Content

Linux debian bash.
I have a PATH type variable ‘X’ that I want to manipulate.
‘X’ can be any number of elements delimited by ":"
For example, using fruits:

set X=apple:pear:orange:cherry

How might I extract the first element minus its delimiter, saving it into a new variable ‘Y’, and then remove it and its delimiter from ‘X’. As in..

apple:pear:orange:cherry

becomes

Y=apple
X=pear:orange:cherry

I have looked at bash substitution cheat sheets, but it’s mind boggling. Sed is also a way, but I can never seem to get rid of the delimiters.

I did get this far

IFS=: arr=($X)
Y=${arr[0]}
cnt=${#arr[@]}
IFS=

Which isn’t very far, but at least I get Y but it doesn’t do anything with X. To be honest, I dont understand them anyway , just used a cheat sheet. So explanations with solutions would be appreciated.

2

Answers


  1. You could:

    X=apple:pear:orange:cherry
    IFS=: read -r Y X <<<"$X"    # note - will fail with newlines
    declare -p Y X
    # declare -- Y="apple"
    # declare -- X="pear:orange:cherry"
    

    read will assign the first element to Y and then the rest to X. For more information, see documentation of read and of your shell, in particular man 1p read and bash manual and POSIX read.

    But using arrays with splitting would be fine too. Fun fact – it can be one line.

    X=apple:pear:orange:cherry
    IFS=:
    arr=($X)
    Y=${arr[0]}
    X="${arr[*]:1}"
    declare -p Y X
    # declare -- Y="apple"
    # declare -- X="pear:orange:cherry"
    

    ($X) will do word splitting expansion and assign an array. With ${arr[0] the first element is extracted. The arr[*] joins the array elements using first character in IFS and using ${ :1} expansion all elements except the first are extracted, see shell parameter expansions.

    Login or Signup to reply.
  2. You can split your colon-separated string up into an array, manipulate that, and then rebuild a new string:

    #!/usr/bin/env bash
    
    x=apple:pear:orange:cherry
    
    echo "x is $x"
    
    
    IFS=:
    # Split x up into an array using the value of IFS as the delimiter.
    read -r -a xarr <<< "$x"
    # Assign the first element to y
    y=${xarr[0]}
    # And remove it from the array.
    unset "xarr[0]"
    # Rebuild x without the first element.
    x="${xarr[*]}"
    unset -v IFS
    
    echo "y is $y and x is now $x"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search