2016-11-04 3 views
0

Я пытаюсь объединить столбцы из двух разных файлов в следующем скрипте:команда пасты в сценарии оболочки

#!/bin/sh 
# 
# 

echo "1 1 1" > tmp1 
echo "2 2 2" >> tmp1 
echo "3 3 3" >> tmp1 

echo "a,b,c" > tmp2 
echo "a,b,c" >> tmp2 
echo "a,b,c" >> tmp2 

paste -d':' <(cut -d" " -f1 tmp1) <(cut -d"," -f 1-2 tmp2) 

Данный скрипт работает отлично, когда я бегу

bash test.sh 

Однако, это делает не работает, когда я бегу

sh test.sh 

и я получаю следующее сообщение об ошибке

test.sh: line 13: syntax error near unexpected token `(' 
test.sh: line 13: `paste -d':' <(cut -d" " -f1 tmp1) <(cut -d"," -f 1-2 tmp2)' 

Может ли кто-нибудь объяснить, в чем причина такого поведения? Это исправить? Спасибо.

+0

[ 'sh'] (https://en.wikipedia.org/wiki/Bourne_shell) и [' bash'] (https://en.wikipedia.org/wiki/Bash_ (Unix_shell)) являются отдельными программами (хотя в некоторых системах 'sh' указывается на' bash' по причинам совместимости). Фактически нет причин когда-либо использовать 'sh'. – dimo414

+0

@ dimo414 Если, конечно, вы не пытаетесь написать сценарий, который будет работать в любой POSIX-совместимой системе, независимо от того, установлен ли он 'bash'. – chepner

+0

@chepner, таким образом, «эффективно» :) Но если вы намерены написать сценарий Bash и не пытаетесь поддерживать каждую среду POSIX только для обратной среды, которую можно было бы состряпать, то «sh'-compliant - лишняя хлопот. – dimo414

ответ

1

В вашей системе sh предположительно не указан как bash (dash может быть?).

Замена способа, <(), is bash -ism (исходит от ksh фактически), который не определен POSIX, следовательно, не переносится.

Так оболочка вы используете (sh) не имеет <() реализации, следовательно, синтаксическую ошибку ( (как < указывает перенаправление ввода, поэтому ошибка фактически показано на первом ().

0

Вы можете реализовать это переносимо, используя дескрипторы

while 
    IFS=" " read -r x rest <&3 
    IFS="," read -r y z rest <&4 
do 
    echo "$x:$y:$z" 
done 3<tmp1 4<tmp2 
1:a:b 
2:a:b 
3:a:b 

файла Испытан с тиром

0

<() обеспечивает синтаксическую альтернативу вручную управлять именованными каналами.

trap 'rm p1 p2' EXIT 
mkfifo p1 p2 
cut -d " " -f1 tmp1 > p1 & 
cut -d " " -f 1-2 tmp2 > p2 & 

paste -d':' p1 p2