Eu quero executar um comando java uma vez para cada correspondência de ls | grep pattern -
. Nesse caso, acho que poderia fazer, find pattern -exec java MyProg '{}' \;
mas estou curioso sobre o caso geral - existe uma maneira fácil de dizer "executar um comando uma vez para cada linha de entrada padrão"? (Em peixes ou bash.)
162
printf "foo bar\nbaz bat" | xargs echo whee
vai renderwhee foo bar baz bat
. Talvez adicione as opções-L
ou-n
?A resposta aceita tem a idéia certa, mas a chave é passar
xargs
a-n1
chave, o que significa "Executar o comando uma vez por linha de saída:"Ou, para um único arquivo de entrada, você pode evitar
cat
totalmente o canal e apenas seguir com:fonte
xargs
da não correr sestdin
estiver vazia:--no-run-if-empty
-r
: Se a entrada padrão não contém quaisquer nonblanks, não execute o comando. Normalmente, o comando é executado uma vez, mesmo que não haja entrada. Esta opção é uma extensão GNU.command
?No Bash ou em qualquer outro shell no estilo Bourne (ash, ksh, zsh,…):
read -r
lê uma única linha da entrada padrão (read
sem-r
interpretar barras invertidas, você não deseja isso). Assim, você pode executar um dos seguintes procedimentos:fonte
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
, não funcionou. Ele trabalhou com um arquivo canalizado nowhile
loop, trabalhou apenas comtail -f
, trabalhou com apenasgrep
, mas não com os dois tubos. Dando ogrep
a--line-buffered
opção fez trabalhocommand | while read -r line; do echo "$line" | command ; done
Concordo com Keith, xargs é a ferramenta mais geral para o trabalho.
Eu costumo usar uma abordagem de 3 etapas.
Existem maneiras menores e mais rápidas, mas essas formas quase sempre funcionam.
Um exemplo simples:
as 2 primeiras linhas selecionam alguns arquivos para trabalhar e, em seguida, o awk prepara uma boa sequência com um comando a ser executado e alguns argumentos e $ 1 é a primeira entrada de coluna do canal. E, finalmente, garanto que o xargs envie essa string para o bash que apenas a executa.
É um pouco exagerado, mas esta receita me ajudou em muitos lugares, pois é muito flexível.
fonte
xargs -0
usa o byte nulo como um separador de registro, assim que sua declaração de impressão awk deve serprintf("MyJavaProg --args \"%s\"\0",$1)
awk
você pode tê-lo fazer o jogo padrão e ignorar ogrep
exemplo,ls | awk '/xls/ {print...
O GNU Parallel é feito para esse tipo de tarefa. O uso mais simples é:
Assista ao vídeo de introdução para saber mais: http://www.youtube.com/watch?v=OpaiGYxkSuQ
fonte
cat
aqui desdegrep
pode ler diretamente o arquivo< stuff grep pattern
mas égrep pattern stuff
sem redirecionamento ou gato necessário. Ainda assim, isso não materialmente alterar o seu argumento e se você acha que é mais claro para usar sempre as coisas de uma tubulação que começa comcat
, em seguida, poder para vocêAlém disso, faça um
while read
loop na casca do peixe (presumo que você queira a casca do peixe, considerando que você usou a etiqueta do peixe ).Alguns pontos a serem observados.
read
não aceita-r
argumentos e não interpreta suas barras invertidas, para facilitar o caso de uso mais comum.$line
, pois ao contrário do bash, o peixe não separa variáveis por espaços.command
por si só, é um erro de sintaxe (para capturar esse uso de argumentos de espaço reservado). Substitua-o pelo comando real.fonte
while
precisa ser emparelhado comdo
& emdone
vez deend
?Se você precisar controlar onde exatamente o argumento de entrada será inserido em sua linha de comandos ou se precisar repeti-lo várias vezes, precisará usar
EXEMPLO 1xargs -I{}
.Crie uma estrutura de pastas vazia
EXEMPLO # 2another_folder
que espelha as subpastas no diretório atual:Aplique uma operação em uma lista de arquivos provenientes de stdin, neste caso, faça uma cópia de cada
.html
arquivo anexando uma.bak
extensão:Na
xargs
página de manual do MacOS / BSD :xargs
Página de manual do Linux :fonte
Ao lidar com entradas potencialmente não autorizadas, eu gosto de ver todo o trabalho 'detalhado', linha por linha, para inspeção visual antes de executá-lo (especialmente quando é algo destrutivo, como limpar a caixa de correio das pessoas).
Então, o que eu faço é gerar uma lista de parâmetros (por exemplo, nomes de usuário), alimentá-lo com um arquivo de um registro por linha, assim:
Em seguida, abro a lista
vim
e a manuseio com expressões de pesquisa e substituição até obter uma lista de comandos completos que precisam ser executados, assim:Dessa forma, se o seu regex estiver incompleto, você verá em qual comando haverá problemas em potencial (ie.
/bin/rm -fr johnnyo connor
). Dessa forma, você pode desfazer seu regex e tentar novamente com uma versão mais confiável. A confusão de nomes é notória por isso, porque é difícil cuidar de todos os casos extremos, como Van Gogh, O'Connors, St. Clair, Smith-Wesson.Ter
set hlsearch
é útil para fazer issovim
, pois destacará todas as correspondências, para que você possa identificar facilmente se não corresponder ou corresponder de forma não intencional.Uma vez que seu regex é perfeito e captura todos os casos em que você pode testar / pensar, geralmente o converto em uma expressão sed para que possa ser totalmente automatizado para outra execução.
Nos casos em que o número de linhas de entrada o impede de fazer uma inspeção visual, recomendo repetir o comando na tela (ou, melhor ainda, em um log) antes de executar, portanto, se ocorrer um erro, você saberá exatamente qual comando causou falhar. Depois, você pode voltar ao seu regex original e ajustar novamente.
fonte
Se um programa ignora o canal, mas aceita arquivos como argumentos, basta apontá-lo para o arquivo especial
/dev/stdin
.Eu não estou familiarizado com java, mas aqui está um exemplo de como você faria isso para o bash:
O $ é necessário para que o bash se traduza
\n
em novas linhas. Não sei por que.fonte
Eu prefiro isso - permitindo comandos de várias linhas e código claro
ref https://stackoverflow.com/a/3891678/248616
fonte
Aqui, um copypaste que você pode usar imediatamente:
O item da lista será colocado onde {} está e o restante do comando e parâmetros serão usados como estão.
fonte