Passando dois argumentos para um comando usando pipes

19

Normalmente, só precisamos passar um argumento:

echo abc | cat
echo abc | cat some_file -
echo abc | cat - some_file

Existe uma maneira de passar dois argumentos? Algo como

{echo abc , echo xyz} | cat
cat 'echo abc' 'echo xyz'

Eu poderia apenas armazenar os dois resultados em um arquivo primeiro

echo abc > file1
echo xyz > file2
cat file1 file2

Mas eu posso acidentalmente substituir um arquivo, o que não é bom. Isso está indo para um script não interativo. Basicamente, eu preciso de uma maneira de passar os resultados de dois comandos arbitrários para cat sem gravar em um arquivo.

ATUALIZAÇÃO: Desculpe, o exemplo mascara o problema. Embora { echo abc ; echo xyz ; } | cat pareça funcionar, a saída é devida ao echo s, não ao cat .

Um exemplo melhor seria { cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d, , o que não funciona como esperado.

com

file1:
a,b
c,d

file2:
1,2
3,4

A saída esperada é:

b,1
d,3

RESOLVIDO:

Use a substituição de processos : cat <(command1) <(command2)

Como alternativa, crie pipes nomeados usando mkfifo :

mkfifo temp1
mkfifo temp2
command1 > temp1 &
command2 > temp2 &
cat temp1 temp2

Menos elegante e mais detalhado, mas funciona bem, desde que você tenha certeza que temp1 e temp2 não existam antes.

    
por goweon 01.08.2011 / 22:54

3 respostas

15

Acho que você deseja o link "Substituição de processo". Ele também funciona no zsh, embora tenha mais opções e a sintaxe seja diferente.

Cria um pseudo arquivo ( /dev/fd/something ) para cada substituição. É muito útil. O comando só pode ler como um fluxo, o que significa que não pode ir e voltar com fseek. Ele precisa lê-lo como um fluxo de bytes, como um pipe.

Seus exemplos funcionam como uma substituição de processo:

cat <(echo abc) <(echo xyz)
paste -d, <(cut -f2 -d, file1) <(cut -f1 -d, file2)

Pense nisso como uma ferramenta para usar um processo e fingir ser um arquivo sem arquivos temporários.

(da minha resposta anterior )

    
por 02.08.2011 / 00:37
2

Eu gosto de xargs Por exemplo, eu quero encontrar o tamanho de todos os dados mysql em / usr / local

osx:local user$ pwd
/usr/local
osx:local user$  ls | grep mysql 
mysql
mysql-5.0.51a-osx10.5-x86_64
mysql-5.0.51b-osx10.5-x86_64
mysql-5.1.39-osx10.5-x86_64
mysql-5.6.17-osx10.7-x86_64
os x:local user$  ls | grep mysql |sudo  xargs du -sh
4.0K    mysql
2.8G    mysql-5.0.51a-osx10.5-x86_64
 10G    mysql-5.0.51b-osx10.5-x86_64
 25G    mysql-5.1.39-osx10.5-x86_64
753M    mysql-5.6.17-osx10.7-x86_64
osx:local user$ 

xargs

    
por 29.05.2014 / 10:29
1

As chaves realmente funcionaram porque o operador de pipe conectará as saídas padrão dos comandos agrupados na entrada padrão do terceiro.

Você pode dizer que a impressão não é dos ecos executando qualquer comando que não use entrada padrão, por exemplo, { echo 1; echo 2;} | echo 3 imprimirá 3 ao contrário de 1 \ n2 \ n3.

No entanto, isso não é o que você queria, porque os dois comandos nas chaves estão gravando na mesma saída, que é como cat -ing seus resultados. Para gerar dois resultados diferentes para usar como os dois argumentos para comandos como paste , você terá que usar um arquivo temporário ou um pipe nomeado.

Você pode usar mktemp para gerar um arquivo temporário exclusivo ou mkfifo para criar um arquivo de pipe FIFO.

    
por 01.08.2011 / 23:46