Is there similar Python zip() functionailty in bash? To be specific, I\'m looking for the equivilent functionality in bash without using python:
$ echo \"A\" >
You could do it in two steps with cat -n
followed by join
. (cat -n
reproduces your file with line numbers at the start of each line. join
joins the two files on the line numbers.)
$ echo "A" > test_a
$ echo "B" >> test_a
$ echo "X" > test_b
$ echo "Y" >> test_b
$ cat -n test_a > test_a.numbered
$ cat -n test_b > test_b.numbered
$ join -o 1.2 -o 2.2 test_a.numbered test_b.numbered
A X
B Y
code
[tmp]$ echo "A" > test_a
[tmp]$ echo "B" >> test_a
[tmp]$ echo "1" > test_b
[tmp]$ echo "2" >> test_b
[tmp]$ cat test_a
A
B
[tmp]$ cat test_b
1
2
[tmp]$ paste test_a test_b > test_c
[tmp]$ cat test_c
A 1
B 2
Here's another way using the paste
command:
$ echo A > test_a
$ echo B >> test_a
$ echo X > test_b
$ echo Y >> test_b
$ paste test_a test_b | while read a b; do echo "$a, $b"; done
A, X
B, Y
You can do all sorts of fun stuff this way using process substitution, like
$ paste <(seq 1 3) <(seq 20 22) | while read a b ; do echo "$a = $b"; done
1 = 20
2 = 21
3 = 22
Be careful though, as when one of the arrays is longer, the variables can get mixed up:
$ paste <(seq 1 3) <(seq 20 25) | while read a b ; do echo "$a = $b"; done
1 = 20
2 = 21
3 = 22
23 =
24 =
25 =
This solution scales to any number of variables:
$ paste <(seq 1 3) \
$ <(seq 20 22) \
$ <(echo first; echo second; echo third) \
$ <(head -n3 /etc/passwd) | while read a b c d ; do echo "$a = $b = $c = $d"; done
1 = 20 = first = root:x:0:0:root:/root:/bin/bash
2 = 21 = second = daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
3 = 22 = third = bin:x:2:2:bin:/bin:/usr/sbin/nologin
Pure bash:
liori@marvin:~$ zip34() { while read word3 <&3; do read word4 <&4 ; echo $word3 $word4 ; done }
liori@marvin:~$ zip34 3<a 4<b
alpha one
beta two
gamma three
delta four
epsilon five
liori@marvin:~$
(old answer) Look at join
.
liori:~% cat a
alpha
beta
gamma
delta
epsilon
liori:~% cat b
one
two
three
four
five
liori:~% join =(cat -n a) =(cat -n b)
1 alpha one
2 beta two
3 gamma three
4 delta four
5 epsilon five
(assuming you've got the =() operator like in zsh, otherwise it's more complicated).