Поведение python zip() в bash?
Существует ли аналогичная функция Python zip() в bash? Чтобы быть конкретным, я ищу эквивалентную функциональность в bash без использования 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
Ответы
Ответ 1
Pure bash:
[email protected]:~$ zip34() { while read word3 <&3; do read word4 <&4 ; echo $word3 $word4 ; done }
[email protected]:~$ zip34 3<a 4<b
alpha one
beta two
gamma three
delta four
epsilon five
[email protected]:~$
(старый ответ) Посмотрите 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
(предположим, что у вас есть оператор =()
, как в zsh
, в противном случае это более сложно).
Ответ 2
код
[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
Ответ 3
Вы можете сделать это в два этапа с cat -n
, а затем join
. (cat -n
воспроизводит ваш файл с номерами строк в начале каждой строки. join
объединяет два файла в номерах строк.)
$ 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
Ответ 4
Вот еще один способ, используя команду paste
:
$ 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
Вы можете делать всякие забавные вещи, используя подстановку процессов, например,
$ paste <(seq 1 3) <(seq 20 22) | while read a b ; do echo "$a = $b"; done
1 = 20
2 = 21
3 = 22
Будьте осторожны, поскольку, когда один из массивов длиннее, переменные могут перепутаться:
$ 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 =
Это решение масштабируется до любого количества переменных:
$ 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