How to merge two arrays in a zipper like fashion in Bash?

后端 未结 5 1812
野趣味
野趣味 2020-11-29 13:23

I am trying to merge two arrays into one in a zipper like fashion. I have difficulty to make that happen.

array1=(one three five seven)
array2=(two four six          


        
相关标签:
5条回答
  • 2020-11-29 13:31

    < Update >This below solution is designed to work with data delimited by newlines: each value to be loaded into the array on a separate line in each file. Works perfectly as written, but if your data is organized differently, please see @Socowi 's alternative using paste with printf in the comments. Much thanks to @Socowi for both raising the issue & offering a workaround for data delimited in other ways! < / Update >

    Here's another solution to interleave data from (2) arrays which are populated with data delimited by newlines in separate files. This solution uses paste, echo & xargs:

    Array Data: I feed files to arrays because I like to disaggregate data from code. Following files with each value delimited by a newline will be consumed by readarray:

    test1.txt:

    one
    three
    five
    seven
    

    test2.txt:

    two
    four
    six
    eight
    

    Put it all together:

    #!/bin/bash
    
    readarray arrayTest1 < /root/test1.txt
    readarray arrayTest2 < /root/test2.txt
    
    paste <( echo "${arrayTest1[*]}" ) <( echo "${arrayTest2[*]}" ) | xargs
    

    Output:

    one two three four five six seven eight
    
    0 讨论(0)
  • 2020-11-29 13:36

    This is based on RTLinuxSW's answer, with the improvement from Paused until further notice's comment, which adds support for sparse and associative arrays.

    for index in "${!array1[@]}"; do  # Also, quote indices
        result+=( "${array1[$index]}" "${array2[$index]}" )
    done
    

    After:

    $ echo "${result[@]}"
    one two three four five six seven eight
    $ declare -p result
    declare -a result=([0]="one" [1]="two" [2]="three" [3]="four" [4]="five" [5]="six" [6]="seven" [7]="eight")
    

    This assumes the indices of the two arrays are identical.

    0 讨论(0)
  • 2020-11-29 13:42

    You can easily read the files, create an array with their content, check who is the bigger one and make the loop.

    #!/usr/bin/env bash
    
    ## Writting a until d into the file file01 and writing 1 until 3 into the file file02.
    echo {a..d} | tee file01
    echo {1..3} | tee file02
    
    ## Declaring two arrays (FILE01 and FILE02) and a variable as integer.
    declare -a FILE01=($(<file1))
    declare -a FILE02=($(<file2))
    declare -i COUNT=0
    
    ## Checking who is the biggest array and declaring the ARRAY_SIZE.
    [[ "${#FILE01[@]}" -ge "${#FILE02[@]}" ]] && declare -i ARRAY_SIZE="${#FILE01[@]}" || declare -i ARRAY_SIZE="${#FILE02[@]}"
    
    ## Creating the loop (COUNT must be lesser or equal ARRAY_SIZE) and print each element of each array (FILE01 and FILE02).
    while [ ${COUNT} -le ${ARRAY_SIZE} ]; do
      echo -n "${FILE01[$COUNT]} ${FILE02[$COUNT]} "
      ((COUNT++))
    done
    

    declare -a -> It creates an array

    declare -i -> It declares the var as integer

    ${#FILE01[@]} -> It's to get the array size

    0 讨论(0)
  • 2020-11-29 13:57

    Assuming both arrays are the same size,

    unset result
    for (( i=0; i<${#array1[*]}; ++i)); do
        result+=( "${array1[$i]}" "${array2[$i]}" )
    done
    
    0 讨论(0)
  • 2020-11-29 13:57

    I've found more common the case where I want to zip two arrays into two columns. This isn't as natively Zsh as the "RTLinuxSW" answer, but for this case, I use paste.

    % tabs 16
    % paste <(print -l $array1) <(print -l $array2)
    one     two
    three   four
    five    six
    seven   eight
    

    And then can shove that into another array to get the intended output:

    % array3=( `!!`«tab»«tab» )
    % print $array3
    one two three four five six seven eight
    
    0 讨论(0)
提交回复
热议问题