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





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







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 15 hours ago
























      asked 17 hours ago









      forthrin

      665519




      665519




















          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
            15 hours ago







          • 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
            15 hours ago

















          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
              17 hours ago











            • @forthrin What is the other command?
              – Kusalananda
              17 hours ago










            • @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
              17 hours ago


















            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
              16 hours ago










            • @Kusalananda noted and answer updated +1
              – thatgeeman
              15 hours ago










            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
              15 hours ago







            • 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
              15 hours ago














            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
              15 hours ago







            • 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
              15 hours ago












            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 13 hours ago









            Stéphane Chazelas

            277k52511841




            277k52511841











            answered 15 hours ago









            Kusalananda

            100k13199311




            100k13199311











            • 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
              15 hours ago







            • 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
              15 hours ago
















            • 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
              15 hours ago







            • 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
              15 hours ago















            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
            15 hours ago





            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
            15 hours ago





            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
            15 hours ago




            @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
            15 hours ago












            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 17 hours ago









                Stéphane Chazelas

                277k52511841




                277k52511841




















                    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
                      17 hours ago











                    • @forthrin What is the other command?
                      – Kusalananda
                      17 hours ago










                    • @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
                      17 hours ago















                    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
                      17 hours ago











                    • @forthrin What is the other command?
                      – Kusalananda
                      17 hours ago










                    • @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
                      17 hours ago













                    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 17 hours ago


























                    answered 17 hours ago









                    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
                      17 hours ago











                    • @forthrin What is the other command?
                      – Kusalananda
                      17 hours ago










                    • @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
                      17 hours ago

















                    • "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
                      17 hours ago











                    • @forthrin What is the other command?
                      – Kusalananda
                      17 hours ago










                    • @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
                      17 hours ago
















                    "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
                    17 hours ago





                    "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
                    17 hours ago













                    @forthrin What is the other command?
                    – Kusalananda
                    17 hours ago




                    @forthrin What is the other command?
                    – Kusalananda
                    17 hours ago












                    @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
                    17 hours ago





                    @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
                    17 hours ago











                    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
                      16 hours ago










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      15 hours ago














                    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
                      16 hours ago










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      15 hours ago












                    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 15 hours ago


























                    answered 16 hours ago









                    thatgeeman

                    876




                    876







                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      16 hours ago










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      15 hours ago












                    • 1




                      The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                      – Kusalananda
                      16 hours ago










                    • @Kusalananda noted and answer updated +1
                      – thatgeeman
                      15 hours ago







                    1




                    1




                    The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                    – Kusalananda
                    16 hours ago




                    The first explicit split() is not necessary as awk already has split the line into $1 and $2.
                    – Kusalananda
                    16 hours ago












                    @Kusalananda noted and answer updated +1
                    – thatgeeman
                    15 hours ago




                    @Kusalananda noted and answer updated +1
                    – thatgeeman
                    15 hours ago












                     

                    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













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation