如何在 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 的替代方案,使用 paste
和 printf
在评论中。非常感谢@Socowi 提出问题并为以其他方式分隔的数据提供解决方法! 更新>
这是另一种解决方案,用于交错来自 (2) 个数组的数据,这些数组填充了由单独文件中的换行符分隔的数据。此解决方案使用 paste
、echo
& 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")
这假设两个数组的索引相同。
我正在尝试以一种时尚的拉链方式将两个数组合并为一个数组。我很难做到这一点。
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 的替代方案,使用 paste
和 printf
在评论中。非常感谢@Socowi 提出问题并为以其他方式分隔的数据提供解决方法! 更新>
这是另一种解决方案,用于交错来自 (2) 个数组的数据,这些数组填充了由单独文件中的换行符分隔的数据。此解决方案使用 paste
、echo
& 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
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")
这假设两个数组的索引相同。