Por que esse comando xargs não funciona?

13

Eu queria excluir todas as extensões .sh assim:

ls *.sh | xargs -I {} mv {} 'basename {} .sh'

No entanto, isso não funciona, ele se comporta como basename retorna o nome do arquivo inalterado.

Por que está se comportando dessa maneira?

Por exemplo, isso funciona:

ls *.sh | xargs -I {} echo 'basename {}.jpg .jpg';

EDITAR :

Solução: a aspas simples evita a avaliação de 'basename ...' pelo shell antes que o comando seja executado.

ls *.sh | xargs -I {}  sh -c 'mv {} 'basename {} .sh''
    
por majkinetor 18.02.2013 / 19:37

2 respostas

11

Como o comando basename é executado antes de o pipeline ser executado. Para fazer isso funcionar, você precisa de xargs para executar o basename e pode fazer isso com sh -c , por exemplo:

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

Notas:

  • Se você não disser xargs onde inserir os nomes dos arquivos, eles serão adicionados no final da linha de comando.
  • Você deve usar a opção -L1 ou seu equivalente, portanto, xargs somente passa um argumento para sh .
  • O uso da saída de ls pode ter efeitos indesejados .

Editar

Removidas as opções obsoletas, obrigado TechZilla

    
por 18.02.2013 / 21:10
4

Não tenho certeza sobre sua pergunta. Você está realmente perguntando por que sua primeira linha não funciona? Ou você está procurando um método adequado para renomear todos os arquivos .sh?

Supondo que seja o método mais limpo, prefiro preparar opções de comando antes de xargs . Para remover uma extensão de arquivo .sh, muitas vezes considero essa abordagem,

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv
    
por 18.02.2013 / 21:10