如何在 Bash 中像拉链一样合并两个数组?

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

我正在尝试以一种时尚的拉链方式将两个数组合并为一个数组。我很难做到这一点。

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

我试过使用嵌套的 for 循环,但无法弄明白。我不希望输出为 13572468,而是 12345678。

我正在处理的实际脚本在这里 (http://ix.io/iZR)..但它显然没有按预期工作。我要么打印整个 array2(例如 124683),要么只打印第一个索引,如果循环不起作用(例如 12325272)。

那么如何获得输出:

one two three four five six seven eight

上面两个数组?

编辑:我能够用两个 for 循环和 paste (http://ix.io/iZU) 解决它。看看是否有人有更好的解决方案仍然很有趣。所以如果你有时间请看一看。

假设两个数组大小相同,

unset result
for (( i=0; i<${#array1[*]}; ++i)); do
    result+=( "${array1[$i]}" "${array2[$i]}" )
done

我发现更常见的情况是我想将两个数组压缩到 两列。这不像 "RTLinuxSW" 答案那样原生 Zsh,但是 对于这种情况,我使用粘贴。

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

然后可以将其推入另一个数组以获得预期的输出:

% array3=( `!!`«tab»«tab» )
% print $array3
one two three four five six seven eight

您可以轻松读取文件,用它们的内容创建一个数组,检查谁更大,然后进行循环。

#!/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 -> 它创建一个数组

declare -i -> 它将变量声明为整数

${#FILE01[@]} -> 就是获取数组大小

<更新>下面的解决方案旨在处理由换行符分隔的数据 :每个值都将加载到数组中每个文件中单独一行。写得很好,但如果你的数据组织方式不同,请参阅 @Socowi 的替代方案,使用 pasteprintf 在评论中。非常感谢@Socowi 提出问题并为以其他方式分隔的数据提供解决方法!

这是另一种解决方案,用于交错来自 (2) 个数组的数据,这些数组填充了由单独文件中的换行符分隔的数据。此解决方案使用 pasteecho & xargs

数组数据:我将文件提供给数组,因为我喜欢从代码中分解数据。 readarray:

将使用以下每个值由换行符分隔的文件

test1.txt:

one
three
five
seven

test2.txt:

two
four
six
eight

全部放在一起:

#!/bin/bash

readarray arrayTest1 < /root/test1.txt
readarray arrayTest2 < /root/test2.txt

paste <( echo "${arrayTest1[*]}" ) <( echo "${arrayTest2[*]}" ) | xargs

输出:

one two three four five six seven eight

这是基于 RTLinuxSW's , with the improvement from Paused until further notice's ,增加了对稀疏和关联数组的支持。

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

之后:

$ 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")

这假设两个数组的索引相同。