Duplicate elements of an array except the first and last elements

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











up vote
0
down vote

favorite












I have an array, and I would like to repeat each element except the first and last elements.



For example if the array has five elements 1 2 3 4 5, then after repeating, its elements should be 1 2 2 3 3 4 4 5.



My bash commands are



$ newarr=("$myarr[0]")
$ for i in $(seq 1 $(($#myarr[@]-2))) ; do newarr+=( "$myarr[i]" "$myarr[i]"); done
$ newarr+=("$myarr[-1]")


Is there a more clear way than mine?



I am also wondering about how to wrap that into a function which takes myarr as argument, and returns newarr.
(After creating such a function, I will read an array from a file, so that each element stores a line in the file, and then call the function on the array. If creating such a function is not a good approach, let me know.)



Thanks.










share|improve this question



























    up vote
    0
    down vote

    favorite












    I have an array, and I would like to repeat each element except the first and last elements.



    For example if the array has five elements 1 2 3 4 5, then after repeating, its elements should be 1 2 2 3 3 4 4 5.



    My bash commands are



    $ newarr=("$myarr[0]")
    $ for i in $(seq 1 $(($#myarr[@]-2))) ; do newarr+=( "$myarr[i]" "$myarr[i]"); done
    $ newarr+=("$myarr[-1]")


    Is there a more clear way than mine?



    I am also wondering about how to wrap that into a function which takes myarr as argument, and returns newarr.
    (After creating such a function, I will read an array from a file, so that each element stores a line in the file, and then call the function on the array. If creating such a function is not a good approach, let me know.)



    Thanks.










    share|improve this question

























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have an array, and I would like to repeat each element except the first and last elements.



      For example if the array has five elements 1 2 3 4 5, then after repeating, its elements should be 1 2 2 3 3 4 4 5.



      My bash commands are



      $ newarr=("$myarr[0]")
      $ for i in $(seq 1 $(($#myarr[@]-2))) ; do newarr+=( "$myarr[i]" "$myarr[i]"); done
      $ newarr+=("$myarr[-1]")


      Is there a more clear way than mine?



      I am also wondering about how to wrap that into a function which takes myarr as argument, and returns newarr.
      (After creating such a function, I will read an array from a file, so that each element stores a line in the file, and then call the function on the array. If creating such a function is not a good approach, let me know.)



      Thanks.










      share|improve this question















      I have an array, and I would like to repeat each element except the first and last elements.



      For example if the array has five elements 1 2 3 4 5, then after repeating, its elements should be 1 2 2 3 3 4 4 5.



      My bash commands are



      $ newarr=("$myarr[0]")
      $ for i in $(seq 1 $(($#myarr[@]-2))) ; do newarr+=( "$myarr[i]" "$myarr[i]"); done
      $ newarr+=("$myarr[-1]")


      Is there a more clear way than mine?



      I am also wondering about how to wrap that into a function which takes myarr as argument, and returns newarr.
      (After creating such a function, I will read an array from a file, so that each element stores a line in the file, and then call the function on the array. If creating such a function is not a good approach, let me know.)



      Thanks.







      bash array bash-functions






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 17 at 18:46









      Kusalananda

      116k15218352




      116k15218352










      asked Nov 17 at 18:12









      Tim

      1




      1




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          You can get the number of operation down ever so slightly, and skip the call to seq:



          for (( i = 1; i < $#myarr[@] - 1; ++i )); do
          newarr+=( "$myarr[i]" "$myarr[i]" )
          done
          newarr=( "$myarr[0]" "$newarr[@]" "$myarr[-1]" )


          This assumes that newarr is empty to start with. Do unset newarry first if it's not.



          As a function (this modifies the array that is passed):



          dup_interal_items () 
          typeset -n arr=$1
          local tmparr

          for (( i = 1; i < $#arr[@] - 1; ++i )); do
          tmparr+=( "$arr[i]" "$arr[i]" )
          done
          arr=( "$arr[0]" "$tmparr[@]" "$arr[-1]" )



          The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.



          I did it this way rather than returning an array as you can only return an exit status from a function. The other approach would have been to pass both the names of an input array and an output array and use two name-reference variables in the function.



          Or, you could possibly echo or printf the values in the function (in which case you don't have to construct a new array at all) and then parse that data in the main code. The function would then be required to be called inside a command substitution.



          Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.



          Testing:



          $ myarr=( 1 2 3 "here we go" )
          $ dup_interal_items myarr
          $ printf 'Element: %sn' "$myarr[@]"
          Element: 1
          Element: 2
          Element: 2
          Element: 3
          Element: 3
          Element: here we go



          To duplicate all lines of a file except for the first and last line:



          sed -e '1b' -e '$b' -e 'p' <file


          The sed script branches to the end (where there is an implicit print statement) if it's on the first or last line, but prints all other lines (all other lines are therefore both explicitly printed by that last p and implicitly printed).



          Or, as contributed by don_crissti,



          sed 'p;1d;$d' <file


          which explicitly prints each line, then ends the cycle for the first and last line, but prints all other lines implicitly (a second time).



          An equivalent awk program that does not store more than a single line in memory would be non-trivial to write.






          share|improve this answer






















          • Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
            – Tim
            Nov 17 at 21:08











          • @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
            – Kusalananda
            Nov 17 at 21:13










          • Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
            – Tim
            Nov 17 at 22:39










          • @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
            – Kusalananda
            Nov 17 at 22:41






          • 1




            @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
            – Kusalananda
            2 days ago


















          up vote
          1
          down vote













          Try also - no function needed -



          $ ARR=(1 2 3 4 5)
          $ IFS=$'nt '
          $ readarray NEWARR < <(echo "$ARR[*]" | sed '1!p; $d')
          $ echo $NEWARR[@]
          1 2 2 3 3 4 4 5


          or even



          NEWARR=($(printf "%sn" $ARR[@] | sed '1!p; $d'))





          share|improve this answer




















          • Please avoid using variable names in caps (except for environment).
            – Isaac
            2 days ago










          • You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
            – Isaac
            2 days ago

















          up vote
          1
          down vote













          A solution that accepts newlines:



          #!/bin/bash
          arr=( 1 2 "3 3" $'41n42' 5 )

          readarray -t -d $'' newarray < <(printf '%s' "$arr[@]" | sed -z '1!p; $d')

          printf '<%s>n' "$newarr[@]"


          Runs as:



          $ ./script
          <1>
          <2>
          <2>
          <3 3>
          <3 3>
          <41
          42>
          <41
          42>
          <5>





          share|improve this answer




















            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: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            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%2f482372%2fduplicate-elements-of-an-array-except-the-first-and-last-elements%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            You can get the number of operation down ever so slightly, and skip the call to seq:



            for (( i = 1; i < $#myarr[@] - 1; ++i )); do
            newarr+=( "$myarr[i]" "$myarr[i]" )
            done
            newarr=( "$myarr[0]" "$newarr[@]" "$myarr[-1]" )


            This assumes that newarr is empty to start with. Do unset newarry first if it's not.



            As a function (this modifies the array that is passed):



            dup_interal_items () 
            typeset -n arr=$1
            local tmparr

            for (( i = 1; i < $#arr[@] - 1; ++i )); do
            tmparr+=( "$arr[i]" "$arr[i]" )
            done
            arr=( "$arr[0]" "$tmparr[@]" "$arr[-1]" )



            The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.



            I did it this way rather than returning an array as you can only return an exit status from a function. The other approach would have been to pass both the names of an input array and an output array and use two name-reference variables in the function.



            Or, you could possibly echo or printf the values in the function (in which case you don't have to construct a new array at all) and then parse that data in the main code. The function would then be required to be called inside a command substitution.



            Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.



            Testing:



            $ myarr=( 1 2 3 "here we go" )
            $ dup_interal_items myarr
            $ printf 'Element: %sn' "$myarr[@]"
            Element: 1
            Element: 2
            Element: 2
            Element: 3
            Element: 3
            Element: here we go



            To duplicate all lines of a file except for the first and last line:



            sed -e '1b' -e '$b' -e 'p' <file


            The sed script branches to the end (where there is an implicit print statement) if it's on the first or last line, but prints all other lines (all other lines are therefore both explicitly printed by that last p and implicitly printed).



            Or, as contributed by don_crissti,



            sed 'p;1d;$d' <file


            which explicitly prints each line, then ends the cycle for the first and last line, but prints all other lines implicitly (a second time).



            An equivalent awk program that does not store more than a single line in memory would be non-trivial to write.






            share|improve this answer






















            • Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
              – Tim
              Nov 17 at 21:08











            • @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
              – Kusalananda
              Nov 17 at 21:13










            • Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
              – Tim
              Nov 17 at 22:39










            • @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
              – Kusalananda
              Nov 17 at 22:41






            • 1




              @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
              – Kusalananda
              2 days ago















            up vote
            2
            down vote



            accepted










            You can get the number of operation down ever so slightly, and skip the call to seq:



            for (( i = 1; i < $#myarr[@] - 1; ++i )); do
            newarr+=( "$myarr[i]" "$myarr[i]" )
            done
            newarr=( "$myarr[0]" "$newarr[@]" "$myarr[-1]" )


            This assumes that newarr is empty to start with. Do unset newarry first if it's not.



            As a function (this modifies the array that is passed):



            dup_interal_items () 
            typeset -n arr=$1
            local tmparr

            for (( i = 1; i < $#arr[@] - 1; ++i )); do
            tmparr+=( "$arr[i]" "$arr[i]" )
            done
            arr=( "$arr[0]" "$tmparr[@]" "$arr[-1]" )



            The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.



            I did it this way rather than returning an array as you can only return an exit status from a function. The other approach would have been to pass both the names of an input array and an output array and use two name-reference variables in the function.



            Or, you could possibly echo or printf the values in the function (in which case you don't have to construct a new array at all) and then parse that data in the main code. The function would then be required to be called inside a command substitution.



            Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.



            Testing:



            $ myarr=( 1 2 3 "here we go" )
            $ dup_interal_items myarr
            $ printf 'Element: %sn' "$myarr[@]"
            Element: 1
            Element: 2
            Element: 2
            Element: 3
            Element: 3
            Element: here we go



            To duplicate all lines of a file except for the first and last line:



            sed -e '1b' -e '$b' -e 'p' <file


            The sed script branches to the end (where there is an implicit print statement) if it's on the first or last line, but prints all other lines (all other lines are therefore both explicitly printed by that last p and implicitly printed).



            Or, as contributed by don_crissti,



            sed 'p;1d;$d' <file


            which explicitly prints each line, then ends the cycle for the first and last line, but prints all other lines implicitly (a second time).



            An equivalent awk program that does not store more than a single line in memory would be non-trivial to write.






            share|improve this answer






















            • Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
              – Tim
              Nov 17 at 21:08











            • @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
              – Kusalananda
              Nov 17 at 21:13










            • Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
              – Tim
              Nov 17 at 22:39










            • @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
              – Kusalananda
              Nov 17 at 22:41






            • 1




              @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
              – Kusalananda
              2 days ago













            up vote
            2
            down vote



            accepted







            up vote
            2
            down vote



            accepted






            You can get the number of operation down ever so slightly, and skip the call to seq:



            for (( i = 1; i < $#myarr[@] - 1; ++i )); do
            newarr+=( "$myarr[i]" "$myarr[i]" )
            done
            newarr=( "$myarr[0]" "$newarr[@]" "$myarr[-1]" )


            This assumes that newarr is empty to start with. Do unset newarry first if it's not.



            As a function (this modifies the array that is passed):



            dup_interal_items () 
            typeset -n arr=$1
            local tmparr

            for (( i = 1; i < $#arr[@] - 1; ++i )); do
            tmparr+=( "$arr[i]" "$arr[i]" )
            done
            arr=( "$arr[0]" "$tmparr[@]" "$arr[-1]" )



            The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.



            I did it this way rather than returning an array as you can only return an exit status from a function. The other approach would have been to pass both the names of an input array and an output array and use two name-reference variables in the function.



            Or, you could possibly echo or printf the values in the function (in which case you don't have to construct a new array at all) and then parse that data in the main code. The function would then be required to be called inside a command substitution.



            Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.



            Testing:



            $ myarr=( 1 2 3 "here we go" )
            $ dup_interal_items myarr
            $ printf 'Element: %sn' "$myarr[@]"
            Element: 1
            Element: 2
            Element: 2
            Element: 3
            Element: 3
            Element: here we go



            To duplicate all lines of a file except for the first and last line:



            sed -e '1b' -e '$b' -e 'p' <file


            The sed script branches to the end (where there is an implicit print statement) if it's on the first or last line, but prints all other lines (all other lines are therefore both explicitly printed by that last p and implicitly printed).



            Or, as contributed by don_crissti,



            sed 'p;1d;$d' <file


            which explicitly prints each line, then ends the cycle for the first and last line, but prints all other lines implicitly (a second time).



            An equivalent awk program that does not store more than a single line in memory would be non-trivial to write.






            share|improve this answer














            You can get the number of operation down ever so slightly, and skip the call to seq:



            for (( i = 1; i < $#myarr[@] - 1; ++i )); do
            newarr+=( "$myarr[i]" "$myarr[i]" )
            done
            newarr=( "$myarr[0]" "$newarr[@]" "$myarr[-1]" )


            This assumes that newarr is empty to start with. Do unset newarry first if it's not.



            As a function (this modifies the array that is passed):



            dup_interal_items () 
            typeset -n arr=$1
            local tmparr

            for (( i = 1; i < $#arr[@] - 1; ++i )); do
            tmparr+=( "$arr[i]" "$arr[i]" )
            done
            arr=( "$arr[0]" "$tmparr[@]" "$arr[-1]" )



            The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.



            I did it this way rather than returning an array as you can only return an exit status from a function. The other approach would have been to pass both the names of an input array and an output array and use two name-reference variables in the function.



            Or, you could possibly echo or printf the values in the function (in which case you don't have to construct a new array at all) and then parse that data in the main code. The function would then be required to be called inside a command substitution.



            Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.



            Testing:



            $ myarr=( 1 2 3 "here we go" )
            $ dup_interal_items myarr
            $ printf 'Element: %sn' "$myarr[@]"
            Element: 1
            Element: 2
            Element: 2
            Element: 3
            Element: 3
            Element: here we go



            To duplicate all lines of a file except for the first and last line:



            sed -e '1b' -e '$b' -e 'p' <file


            The sed script branches to the end (where there is an implicit print statement) if it's on the first or last line, but prints all other lines (all other lines are therefore both explicitly printed by that last p and implicitly printed).



            Or, as contributed by don_crissti,



            sed 'p;1d;$d' <file


            which explicitly prints each line, then ends the cycle for the first and last line, but prints all other lines implicitly (a second time).



            An equivalent awk program that does not store more than a single line in memory would be non-trivial to write.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 17 at 19:31

























            answered Nov 17 at 18:27









            Kusalananda

            116k15218352




            116k15218352











            • Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
              – Tim
              Nov 17 at 21:08











            • @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
              – Kusalananda
              Nov 17 at 21:13










            • Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
              – Tim
              Nov 17 at 22:39










            • @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
              – Kusalananda
              Nov 17 at 22:41






            • 1




              @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
              – Kusalananda
              2 days ago

















            • Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
              – Tim
              Nov 17 at 21:08











            • @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
              – Kusalananda
              Nov 17 at 21:13










            • Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
              – Tim
              Nov 17 at 22:39










            • @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
              – Kusalananda
              Nov 17 at 22:41






            • 1




              @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
              – Kusalananda
              2 days ago
















            Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
            – Tim
            Nov 17 at 21:08





            Thanks. (1) "you can't call this function with an array called arr due to the particular name scoping rules used by bash." Do you mean arr declared as typeset -n arr=$1 inside the function body has global (script-wide) scope? (2) Among the three approaches when creating a bash function, which one do you suggest more or none?
            – Tim
            Nov 17 at 21:08













            @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
            – Kusalananda
            Nov 17 at 21:13




            @Tim (1) A name reference variable can't reference another variable that has the same name as itself (see also Circular name references in bash shell function, but not in ksh). (2) It depends on what you'd like to do and how you want/need to get there. If the original data was coming from a file, and wasn't used for anything else, I would probably go with reading the array from sed instead of reading it and manipulating it. If the resulting data would go to a file, I would not read it into an array at all.
            – Kusalananda
            Nov 17 at 21:13












            Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
            – Tim
            Nov 17 at 22:39




            Thanks. "If the resulting data would go to a file, I would not read it into an array at all." Could you be more specific?
            – Tim
            Nov 17 at 22:39












            @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
            – Kusalananda
            Nov 17 at 22:41




            @Tim Well, if all you want to do is to duplicate the internal lines of a text file and write that to a new file, then there is that sed command that could do that for you. Why read it into an array in bash?
            – Kusalananda
            Nov 17 at 22:41




            1




            1




            @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
            – Kusalananda
            2 days ago





            @Cbhihe No, you are misreading. It says "Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables." In my code, arr (in the function) is not an array variable, it's an ordinary variable that I give the nameref attribute to. It then references an array variable.
            – Kusalananda
            2 days ago













            up vote
            1
            down vote













            Try also - no function needed -



            $ ARR=(1 2 3 4 5)
            $ IFS=$'nt '
            $ readarray NEWARR < <(echo "$ARR[*]" | sed '1!p; $d')
            $ echo $NEWARR[@]
            1 2 2 3 3 4 4 5


            or even



            NEWARR=($(printf "%sn" $ARR[@] | sed '1!p; $d'))





            share|improve this answer




















            • Please avoid using variable names in caps (except for environment).
              – Isaac
              2 days ago










            • You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
              – Isaac
              2 days ago














            up vote
            1
            down vote













            Try also - no function needed -



            $ ARR=(1 2 3 4 5)
            $ IFS=$'nt '
            $ readarray NEWARR < <(echo "$ARR[*]" | sed '1!p; $d')
            $ echo $NEWARR[@]
            1 2 2 3 3 4 4 5


            or even



            NEWARR=($(printf "%sn" $ARR[@] | sed '1!p; $d'))





            share|improve this answer




















            • Please avoid using variable names in caps (except for environment).
              – Isaac
              2 days ago










            • You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
              – Isaac
              2 days ago












            up vote
            1
            down vote










            up vote
            1
            down vote









            Try also - no function needed -



            $ ARR=(1 2 3 4 5)
            $ IFS=$'nt '
            $ readarray NEWARR < <(echo "$ARR[*]" | sed '1!p; $d')
            $ echo $NEWARR[@]
            1 2 2 3 3 4 4 5


            or even



            NEWARR=($(printf "%sn" $ARR[@] | sed '1!p; $d'))





            share|improve this answer












            Try also - no function needed -



            $ ARR=(1 2 3 4 5)
            $ IFS=$'nt '
            $ readarray NEWARR < <(echo "$ARR[*]" | sed '1!p; $d')
            $ echo $NEWARR[@]
            1 2 2 3 3 4 4 5


            or even



            NEWARR=($(printf "%sn" $ARR[@] | sed '1!p; $d'))






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 17 at 22:12









            RudiC

            3,0911211




            3,0911211











            • Please avoid using variable names in caps (except for environment).
              – Isaac
              2 days ago










            • You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
              – Isaac
              2 days ago
















            • Please avoid using variable names in caps (except for environment).
              – Isaac
              2 days ago










            • You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
              – Isaac
              2 days ago















            Please avoid using variable names in caps (except for environment).
            – Isaac
            2 days ago




            Please avoid using variable names in caps (except for environment).
            – Isaac
            2 days ago












            You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
            – Isaac
            2 days ago




            You should quote variable expansions ($NEWARR[@]) and use -t on readarray to remove the trailing newline of each array element.
            – Isaac
            2 days ago










            up vote
            1
            down vote













            A solution that accepts newlines:



            #!/bin/bash
            arr=( 1 2 "3 3" $'41n42' 5 )

            readarray -t -d $'' newarray < <(printf '%s' "$arr[@]" | sed -z '1!p; $d')

            printf '<%s>n' "$newarr[@]"


            Runs as:



            $ ./script
            <1>
            <2>
            <2>
            <3 3>
            <3 3>
            <41
            42>
            <41
            42>
            <5>





            share|improve this answer
























              up vote
              1
              down vote













              A solution that accepts newlines:



              #!/bin/bash
              arr=( 1 2 "3 3" $'41n42' 5 )

              readarray -t -d $'' newarray < <(printf '%s' "$arr[@]" | sed -z '1!p; $d')

              printf '<%s>n' "$newarr[@]"


              Runs as:



              $ ./script
              <1>
              <2>
              <2>
              <3 3>
              <3 3>
              <41
              42>
              <41
              42>
              <5>





              share|improve this answer






















                up vote
                1
                down vote










                up vote
                1
                down vote









                A solution that accepts newlines:



                #!/bin/bash
                arr=( 1 2 "3 3" $'41n42' 5 )

                readarray -t -d $'' newarray < <(printf '%s' "$arr[@]" | sed -z '1!p; $d')

                printf '<%s>n' "$newarr[@]"


                Runs as:



                $ ./script
                <1>
                <2>
                <2>
                <3 3>
                <3 3>
                <41
                42>
                <41
                42>
                <5>





                share|improve this answer












                A solution that accepts newlines:



                #!/bin/bash
                arr=( 1 2 "3 3" $'41n42' 5 )

                readarray -t -d $'' newarray < <(printf '%s' "$arr[@]" | sed -z '1!p; $d')

                printf '<%s>n' "$newarr[@]"


                Runs as:



                $ ./script
                <1>
                <2>
                <2>
                <3 3>
                <3 3>
                <41
                42>
                <41
                42>
                <5>






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 2 days ago









                Isaac

                9,62411443




                9,62411443



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482372%2fduplicate-elements-of-an-array-except-the-first-and-last-elements%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown






                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay