Splitting string by space character (strange problem with basename)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite












I need to split the output from ps, which is spaced separated.



#!/bin/bash

A=$(ps -r -e -o pcpu=,comm= | head -1)
B=$A[0]
C=$A[1]
printf '%3s %sn' $B $(basename $C)


Output should be:



 42 bar


Instead, I get:



usage: basename ...


Why doesn't this work, and most importantly, how do I make it work?







share|improve this question

























    up vote
    4
    down vote

    favorite












    I need to split the output from ps, which is spaced separated.



    #!/bin/bash

    A=$(ps -r -e -o pcpu=,comm= | head -1)
    B=$A[0]
    C=$A[1]
    printf '%3s %sn' $B $(basename $C)


    Output should be:



     42 bar


    Instead, I get:



    usage: basename ...


    Why doesn't this work, and most importantly, how do I make it work?







    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I need to split the output from ps, which is spaced separated.



      #!/bin/bash

      A=$(ps -r -e -o pcpu=,comm= | head -1)
      B=$A[0]
      C=$A[1]
      printf '%3s %sn' $B $(basename $C)


      Output should be:



       42 bar


      Instead, I get:



      usage: basename ...


      Why doesn't this work, and most importantly, how do I make it work?







      share|improve this question













      I need to split the output from ps, which is spaced separated.



      #!/bin/bash

      A=$(ps -r -e -o pcpu=,comm= | head -1)
      B=$A[0]
      C=$A[1]
      printf '%3s %sn' $B $(basename $C)


      Output should be:



       42 bar


      Instead, I get:



      usage: basename ...


      Why doesn't this work, and most importantly, how do I make it work?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Aug 6 at 9:40
























      asked Aug 6 at 7:48









      forthrin

      800821




      800821




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          Others have already noted what the error in your code is and correctly suggested that for your initial placeholder data, an array would be the better choice of data structure, along with how to make sure you split the string correctly etc.



          Now that we know what your actual command is that you're parsing, we can be slightly more creative with suggestions for improvement.



          The following script will take each of the lines of output of your ps command and read it as two space-delimited bits. The body of the loop output the read bits in different ways:



          #!/bin/bash

          ps -r -e -o pcpu=,comm= |
          while IFS=' ' read -r pcpu comm; do
          printf 'pcpu=%s,tcomm=%s,tbasename of comm=%sn'
          "$pcpu" "$comm" "$comm##*/"
          done


          Here, comm will hold everything after the first sequence of spaces in the output of ps (the initial spaces, before the first column, would be trimmed off).



          You may obviously insert your head -n 1 as a part of the initial pipeline if you wish.



          Note that in some shells, including bash, the loop is running in a subshell, so any variables created there will not be available after the pipeline has finished. There are two solutions to this in bash:



          1. Enable the lastpipe shell option in the script with shopt -s lastpipe, or


          2. Read the data into the loop with a process substitution:



            while IFS=' ' read ...
            # ...
            done < <( ps ... )


          Example run:



          $ bash script.sh
          pcpu=0.0, comm=tmux, basename of comm=tmux
          pcpu=0.0, comm=sh, basename of comm=sh
          pcpu=0.0, comm=sh, basename of comm=sh
          pcpu=0.0, comm=bash, basename of comm=bash
          pcpu=0.0, comm=bash, basename of comm=bash
          pcpu=0.0, comm=bash, basename of comm=bash
          pcpu=0.0, comm=ps, basename of comm=ps
          pcpu=0.0, comm=sh, basename of comm=sh





          share|improve this answer























          • It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
            – forthrin
            Aug 6 at 10:22







          • 2




            @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
            – Kusalananda
            Aug 6 at 10:33

















          up vote
          6
          down vote













          To split a string on space character, you can use the split+glob operator. That's invoked upon command substitution or parameter expansion, but obviously not when storing into a scalar variable which can only store at most one value.



           var=$(...)


          Is a scalar variable assignment. So would assign the whole output to $var, same as $var[0]. For an array variable assignment, it's:



           var=($(...))


          Now, before invoking it, as always, you'd need to tune it:



           set -o noglob # disable the glob part which you don't want here
          IFS=' ' # split on space only
          var=($(some command)) # invoke it


          Note that it splits on sequences of spaces and leading and trailing spaces are ignored.



          Then, you don't want to invoke it on the expansion of $B nor $C nor $(basename...) so you need to quote those:



           printf '%3s %sn' "$B" "$(basename -- "$C")"


          Also don't forget the -- to mark the end of options.



          Because you forgot the quotes around $C ($C being empty in your case as $A[1] was never assigned any value), basename didn't get passed any argument instead of being passed that empty argument and complained about it.






          share|improve this answer




























            up vote
            3
            down vote













            define array using (). If you using double quotes, then it will be taking as whole string.



            Read more about the array



            $ cat test.sh
            #!/bin/bash

            A=(42 /foo/bar)
            B=$A[0]
            C=$A[1]
            printf '%3s %sn' $B $(basename $C)

            $ bash test.sh
            42 bar





            share|improve this answer























            • "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
              – forthrin
              Aug 6 at 8:15











            • @forthrin What is the other command?
              – Kusalananda
              Aug 6 at 8:23










            • @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
              – Stéphane Chazelas
              Aug 6 at 8:25


















            up vote
            0
            down vote













            Another approach using awk:



             echo "42 /foo/bar" | awk 'n=split($2,b,"/"); print $1,b[n]'





            share|improve this answer



















            • 1




              The first explicit split() is not necessary as awk already has split the line into $1 and $2.
              – Kusalananda
              Aug 6 at 9:37










            • @Kusalananda noted and answer updated +1
              – thatgeeman
              Aug 6 at 9:47










            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460774%2fsplitting-string-by-space-character-strange-problem-with-basename%23new-answer', 'question_page');

            );

            Post as a guest






























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            5
            down vote



            accepted










            Others have already noted what the error in your code is and correctly suggested that for your initial placeholder data, an array would be the better choice of data structure, along with how to make sure you split the string correctly etc.



            Now that we know what your actual command is that you're parsing, we can be slightly more creative with suggestions for improvement.



            The following script will take each of the lines of output of your ps command and read it as two space-delimited bits. The body of the loop output the read bits in different ways:



            #!/bin/bash

            ps -r -e -o pcpu=,comm= |
            while IFS=' ' read -r pcpu comm; do
            printf 'pcpu=%s,tcomm=%s,tbasename of comm=%sn'
            "$pcpu" "$comm" "$comm##*/"
            done


            Here, comm will hold everything after the first sequence of spaces in the output of ps (the initial spaces, before the first column, would be trimmed off).



            You may obviously insert your head -n 1 as a part of the initial pipeline if you wish.



            Note that in some shells, including bash, the loop is running in a subshell, so any variables created there will not be available after the pipeline has finished. There are two solutions to this in bash:



            1. Enable the lastpipe shell option in the script with shopt -s lastpipe, or


            2. Read the data into the loop with a process substitution:



              while IFS=' ' read ...
              # ...
              done < <( ps ... )


            Example run:



            $ bash script.sh
            pcpu=0.0, comm=tmux, basename of comm=tmux
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=ps, basename of comm=ps
            pcpu=0.0, comm=sh, basename of comm=sh





            share|improve this answer























            • It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
              – forthrin
              Aug 6 at 10:22







            • 2




              @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
              – Kusalananda
              Aug 6 at 10:33














            up vote
            5
            down vote



            accepted










            Others have already noted what the error in your code is and correctly suggested that for your initial placeholder data, an array would be the better choice of data structure, along with how to make sure you split the string correctly etc.



            Now that we know what your actual command is that you're parsing, we can be slightly more creative with suggestions for improvement.



            The following script will take each of the lines of output of your ps command and read it as two space-delimited bits. The body of the loop output the read bits in different ways:



            #!/bin/bash

            ps -r -e -o pcpu=,comm= |
            while IFS=' ' read -r pcpu comm; do
            printf 'pcpu=%s,tcomm=%s,tbasename of comm=%sn'
            "$pcpu" "$comm" "$comm##*/"
            done


            Here, comm will hold everything after the first sequence of spaces in the output of ps (the initial spaces, before the first column, would be trimmed off).



            You may obviously insert your head -n 1 as a part of the initial pipeline if you wish.



            Note that in some shells, including bash, the loop is running in a subshell, so any variables created there will not be available after the pipeline has finished. There are two solutions to this in bash:



            1. Enable the lastpipe shell option in the script with shopt -s lastpipe, or


            2. Read the data into the loop with a process substitution:



              while IFS=' ' read ...
              # ...
              done < <( ps ... )


            Example run:



            $ bash script.sh
            pcpu=0.0, comm=tmux, basename of comm=tmux
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=ps, basename of comm=ps
            pcpu=0.0, comm=sh, basename of comm=sh





            share|improve this answer























            • It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
              – forthrin
              Aug 6 at 10:22







            • 2




              @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
              – Kusalananda
              Aug 6 at 10:33












            up vote
            5
            down vote



            accepted







            up vote
            5
            down vote



            accepted






            Others have already noted what the error in your code is and correctly suggested that for your initial placeholder data, an array would be the better choice of data structure, along with how to make sure you split the string correctly etc.



            Now that we know what your actual command is that you're parsing, we can be slightly more creative with suggestions for improvement.



            The following script will take each of the lines of output of your ps command and read it as two space-delimited bits. The body of the loop output the read bits in different ways:



            #!/bin/bash

            ps -r -e -o pcpu=,comm= |
            while IFS=' ' read -r pcpu comm; do
            printf 'pcpu=%s,tcomm=%s,tbasename of comm=%sn'
            "$pcpu" "$comm" "$comm##*/"
            done


            Here, comm will hold everything after the first sequence of spaces in the output of ps (the initial spaces, before the first column, would be trimmed off).



            You may obviously insert your head -n 1 as a part of the initial pipeline if you wish.



            Note that in some shells, including bash, the loop is running in a subshell, so any variables created there will not be available after the pipeline has finished. There are two solutions to this in bash:



            1. Enable the lastpipe shell option in the script with shopt -s lastpipe, or


            2. Read the data into the loop with a process substitution:



              while IFS=' ' read ...
              # ...
              done < <( ps ... )


            Example run:



            $ bash script.sh
            pcpu=0.0, comm=tmux, basename of comm=tmux
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=ps, basename of comm=ps
            pcpu=0.0, comm=sh, basename of comm=sh





            share|improve this answer















            Others have already noted what the error in your code is and correctly suggested that for your initial placeholder data, an array would be the better choice of data structure, along with how to make sure you split the string correctly etc.



            Now that we know what your actual command is that you're parsing, we can be slightly more creative with suggestions for improvement.



            The following script will take each of the lines of output of your ps command and read it as two space-delimited bits. The body of the loop output the read bits in different ways:



            #!/bin/bash

            ps -r -e -o pcpu=,comm= |
            while IFS=' ' read -r pcpu comm; do
            printf 'pcpu=%s,tcomm=%s,tbasename of comm=%sn'
            "$pcpu" "$comm" "$comm##*/"
            done


            Here, comm will hold everything after the first sequence of spaces in the output of ps (the initial spaces, before the first column, would be trimmed off).



            You may obviously insert your head -n 1 as a part of the initial pipeline if you wish.



            Note that in some shells, including bash, the loop is running in a subshell, so any variables created there will not be available after the pipeline has finished. There are two solutions to this in bash:



            1. Enable the lastpipe shell option in the script with shopt -s lastpipe, or


            2. Read the data into the loop with a process substitution:



              while IFS=' ' read ...
              # ...
              done < <( ps ... )


            Example run:



            $ bash script.sh
            pcpu=0.0, comm=tmux, basename of comm=tmux
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=sh, basename of comm=sh
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=bash, basename of comm=bash
            pcpu=0.0, comm=ps, basename of comm=ps
            pcpu=0.0, comm=sh, basename of comm=sh






            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Aug 6 at 11:49









            Stéphane Chazelas

            279k53513844




            279k53513844











            answered Aug 6 at 10:11









            Kusalananda

            101k13199312




            101k13199312











            • It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
              – forthrin
              Aug 6 at 10:22







            • 2




              @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
              – Kusalananda
              Aug 6 at 10:33
















            • It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
              – forthrin
              Aug 6 at 10:22







            • 2




              @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
              – Kusalananda
              Aug 6 at 10:33















            It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
            – forthrin
            Aug 6 at 10:22





            It's a fine line knowing how much detail to include, but your suggestion is brilliant, because you guessed the purpose and put forth a very short and UNIX-y solution. I would give two points if I could!
            – forthrin
            Aug 6 at 10:22





            2




            2




            @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
            – Kusalananda
            Aug 6 at 10:33




            @forthrin Whenever I see anyone storing the output of a command into a variable, I'd like to know what the actual command is. Chances are that there's a better way of processing that data than to store it in a variable, especially if the command outputs more than a short simple string that requires no further processing.
            – Kusalananda
            Aug 6 at 10:33












            up vote
            6
            down vote













            To split a string on space character, you can use the split+glob operator. That's invoked upon command substitution or parameter expansion, but obviously not when storing into a scalar variable which can only store at most one value.



             var=$(...)


            Is a scalar variable assignment. So would assign the whole output to $var, same as $var[0]. For an array variable assignment, it's:



             var=($(...))


            Now, before invoking it, as always, you'd need to tune it:



             set -o noglob # disable the glob part which you don't want here
            IFS=' ' # split on space only
            var=($(some command)) # invoke it


            Note that it splits on sequences of spaces and leading and trailing spaces are ignored.



            Then, you don't want to invoke it on the expansion of $B nor $C nor $(basename...) so you need to quote those:



             printf '%3s %sn' "$B" "$(basename -- "$C")"


            Also don't forget the -- to mark the end of options.



            Because you forgot the quotes around $C ($C being empty in your case as $A[1] was never assigned any value), basename didn't get passed any argument instead of being passed that empty argument and complained about it.






            share|improve this answer

























              up vote
              6
              down vote













              To split a string on space character, you can use the split+glob operator. That's invoked upon command substitution or parameter expansion, but obviously not when storing into a scalar variable which can only store at most one value.



               var=$(...)


              Is a scalar variable assignment. So would assign the whole output to $var, same as $var[0]. For an array variable assignment, it's:



               var=($(...))


              Now, before invoking it, as always, you'd need to tune it:



               set -o noglob # disable the glob part which you don't want here
              IFS=' ' # split on space only
              var=($(some command)) # invoke it


              Note that it splits on sequences of spaces and leading and trailing spaces are ignored.



              Then, you don't want to invoke it on the expansion of $B nor $C nor $(basename...) so you need to quote those:



               printf '%3s %sn' "$B" "$(basename -- "$C")"


              Also don't forget the -- to mark the end of options.



              Because you forgot the quotes around $C ($C being empty in your case as $A[1] was never assigned any value), basename didn't get passed any argument instead of being passed that empty argument and complained about it.






              share|improve this answer























                up vote
                6
                down vote










                up vote
                6
                down vote









                To split a string on space character, you can use the split+glob operator. That's invoked upon command substitution or parameter expansion, but obviously not when storing into a scalar variable which can only store at most one value.



                 var=$(...)


                Is a scalar variable assignment. So would assign the whole output to $var, same as $var[0]. For an array variable assignment, it's:



                 var=($(...))


                Now, before invoking it, as always, you'd need to tune it:



                 set -o noglob # disable the glob part which you don't want here
                IFS=' ' # split on space only
                var=($(some command)) # invoke it


                Note that it splits on sequences of spaces and leading and trailing spaces are ignored.



                Then, you don't want to invoke it on the expansion of $B nor $C nor $(basename...) so you need to quote those:



                 printf '%3s %sn' "$B" "$(basename -- "$C")"


                Also don't forget the -- to mark the end of options.



                Because you forgot the quotes around $C ($C being empty in your case as $A[1] was never assigned any value), basename didn't get passed any argument instead of being passed that empty argument and complained about it.






                share|improve this answer













                To split a string on space character, you can use the split+glob operator. That's invoked upon command substitution or parameter expansion, but obviously not when storing into a scalar variable which can only store at most one value.



                 var=$(...)


                Is a scalar variable assignment. So would assign the whole output to $var, same as $var[0]. For an array variable assignment, it's:



                 var=($(...))


                Now, before invoking it, as always, you'd need to tune it:



                 set -o noglob # disable the glob part which you don't want here
                IFS=' ' # split on space only
                var=($(some command)) # invoke it


                Note that it splits on sequences of spaces and leading and trailing spaces are ignored.



                Then, you don't want to invoke it on the expansion of $B nor $C nor $(basename...) so you need to quote those:



                 printf '%3s %sn' "$B" "$(basename -- "$C")"


                Also don't forget the -- to mark the end of options.



                Because you forgot the quotes around $C ($C being empty in your case as $A[1] was never assigned any value), basename didn't get passed any argument instead of being passed that empty argument and complained about it.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Aug 6 at 8:33









                Stéphane Chazelas

                279k53513844




                279k53513844




















                    up vote
                    3
                    down vote













                    define array using (). If you using double quotes, then it will be taking as whole string.



                    Read more about the array



                    $ cat test.sh
                    #!/bin/bash

                    A=(42 /foo/bar)
                    B=$A[0]
                    C=$A[1]
                    printf '%3s %sn' $B $(basename $C)

                    $ bash test.sh
                    42 bar





                    share|improve this answer























                    • "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                      – forthrin
                      Aug 6 at 8:15











                    • @forthrin What is the other command?
                      – Kusalananda
                      Aug 6 at 8:23










                    • @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                      – Stéphane Chazelas
                      Aug 6 at 8:25















                    up vote
                    3
                    down vote













                    define array using (). If you using double quotes, then it will be taking as whole string.



                    Read more about the array



                    $ cat test.sh
                    #!/bin/bash

                    A=(42 /foo/bar)
                    B=$A[0]
                    C=$A[1]
                    printf '%3s %sn' $B $(basename $C)

                    $ bash test.sh
                    42 bar





                    share|improve this answer























                    • "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                      – forthrin
                      Aug 6 at 8:15











                    • @forthrin What is the other command?
                      – Kusalananda
                      Aug 6 at 8:23










                    • @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                      – Stéphane Chazelas
                      Aug 6 at 8:25













                    up vote
                    3
                    down vote










                    up vote
                    3
                    down vote









                    define array using (). If you using double quotes, then it will be taking as whole string.



                    Read more about the array



                    $ cat test.sh
                    #!/bin/bash

                    A=(42 /foo/bar)
                    B=$A[0]
                    C=$A[1]
                    printf '%3s %sn' $B $(basename $C)

                    $ bash test.sh
                    42 bar





                    share|improve this answer















                    define array using (). If you using double quotes, then it will be taking as whole string.



                    Read more about the array



                    $ cat test.sh
                    #!/bin/bash

                    A=(42 /foo/bar)
                    B=$A[0]
                    C=$A[1]
                    printf '%3s %sn' $B $(basename $C)

                    $ bash test.sh
                    42 bar






                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Aug 6 at 8:15


























                    answered Aug 6 at 7:54









                    Kamaraj

                    2,5341312




                    2,5341312











                    • "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                      – forthrin
                      Aug 6 at 8:15











                    • @forthrin What is the other command?
                      – Kusalananda
                      Aug 6 at 8:23










                    • @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                      – Stéphane Chazelas
                      Aug 6 at 8:25

















                    • "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                      – forthrin
                      Aug 6 at 8:15











                    • @forthrin What is the other command?
                      – Kusalananda
                      Aug 6 at 8:23










                    • @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                      – Stéphane Chazelas
                      Aug 6 at 8:25
















                    "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                    – forthrin
                    Aug 6 at 8:15





                    "42 /foo/bar" is actually the output of another command. So then ($(echo 42 /foo/bar)) will work, then! Update the answer and I'll accept it. Good answer with simple explanation.
                    – forthrin
                    Aug 6 at 8:15













                    @forthrin What is the other command?
                    – Kusalananda
                    Aug 6 at 8:23




                    @forthrin What is the other command?
                    – Kusalananda
                    Aug 6 at 8:23












                    @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                    – Stéphane Chazelas
                    Aug 6 at 8:25





                    @forthrin, doing ($(echo 42 /foo/bar)) would invoke the split+glob operator (actually Kamaraj also invoked 3 times by mistake in their answer (in the part copied from your question)), so it would only work properly if $IFS contained space (and no other character, assuming you want to split on space only) and the string didn't contain wildcard characters.
                    – Stéphane Chazelas
                    Aug 6 at 8:25











                    up vote
                    0
                    down vote













                    Another approach using awk:



                     echo "42 /foo/bar" | awk 'n=split($2,b,"/"); print $1,b[n]'





                    share|improve this answer



















                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      Aug 6 at 9:37










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      Aug 6 at 9:47














                    up vote
                    0
                    down vote













                    Another approach using awk:



                     echo "42 /foo/bar" | awk 'n=split($2,b,"/"); print $1,b[n]'





                    share|improve this answer



















                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      Aug 6 at 9:37










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      Aug 6 at 9:47












                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    Another approach using awk:



                     echo "42 /foo/bar" | awk 'n=split($2,b,"/"); print $1,b[n]'





                    share|improve this answer















                    Another approach using awk:



                     echo "42 /foo/bar" | awk 'n=split($2,b,"/"); print $1,b[n]'






                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Aug 6 at 9:46


























                    answered Aug 6 at 9:27









                    thatgeeman

                    977




                    977







                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      Aug 6 at 9:37










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      Aug 6 at 9:47












                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      Aug 6 at 9:37










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      Aug 6 at 9:47







                    1




                    1




                    The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                    – Kusalananda
                    Aug 6 at 9:37




                    The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                    – Kusalananda
                    Aug 6 at 9:37












                    @Kusalananda noted and answer updated +1
                    – thatgeeman
                    Aug 6 at 9:47




                    @Kusalananda noted and answer updated +1
                    – thatgeeman
                    Aug 6 at 9:47












                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460774%2fsplitting-string-by-space-character-strange-problem-with-basename%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    Color the edges and diagonals of a regular polygon

                    Relationship between determinant of matrix and determinant of adjoint?

                    What is the equation of a 3D cone with generalised tilt?