开发者

Python zip() behavior in bash?

开发者 https://www.devze.com 2023-03-08 12:30 出处:网络
Is there similar Python zip()开发者_如何学运维 functionailty in bash? To be specific, I\'m looking for the equivilent functionality in bash without using python:

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" > test_a
$ echo "B" >> test_a
$ echo "1" > test_b
$ echo "2" >> test_b
$ python -c "print '\n'.join([' '.join([a.strip(),b.strip()]) for a,b in zip(open('test_a'),open('test_b'))])"
A 1
B 2


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).


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消