Comandos de tubulação após um xargs canalizados

30

HP-UX ***** B.11.23 U ia64 **** licença de usuário ilimitado

find . -type d -name *log* | xargs ls -la

me fornece os nomes de diretório (aqueles que contêm log no nome do diretório) seguidos por todos os arquivos dentro desse diretório.

Os diretórios /var/opt/SID/application_a/log/ , /var/opt/SID/application_b/log/ , /var/opt/SID/application_c/log/ e assim por diante contêm arquivos de log.

Eu quero apenas que os dois arquivos de log mais recentes sejam listados pelo comando ls , que normalmente encontro usando ls -latr | tail -2 .

A saída tem que ser algo assim ...

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2 não me dá o resultado acima. O que eu recebo é uma lista dos últimos dois arquivos de find . -type d -name *log* | xargs ls -la command.

Então eu posso enviar comandos depois de um xargs ? Como faço para consultar, para obter a lista resultante de arquivos no formato acima?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

me dá uma lista de dez nomes de diretório dentro do diretório atual, que por acaso é /var/opt/SID e que também não é o que eu quero.

    
por user3146086 12.06.2015 / 15:00

3 respostas

44

Você está quase lá. Em seu último comando, você pode usar -I para fazer o ls corretamente

-I replace-str

    Replace occurrences of replace-str in the initial-arguments with names read from standard input.  Also, unquoted blanks do not terminate input items; instead the separator is the newline character.  Implies -x and -L 1.

Então, com

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

você vai echo o diretório encontrado por find , então faça o ls | tail nele.

    
por 12.06.2015 / 15:17
2

O GNU Parallel facilita esse tipo de tarefa:

find . -type d -name "*log*" | parallel --tag "ls -la {} | tail -2"

Se você não quiser fazer uma instalação completa do GNU Parallel, você pode fazer uma instalação mínima: link

    
por 13.08.2017 / 21:57
1

Apenas além de fredtantini e como um esclarecimento geral (já que os documentos são um pouco confusos):

O xargs -I {} pegará os caracteres '{}' da entrada padrão e os substituirá pelo que vier do cano. Isso significa que você pode substituir {} por qualquer combinação de caracteres (talvez para melhor adequar seu sabor de programação preferido). Por exemplo : xargs -I % sh -c "echo %" . Se você sempre usar o xargs -I {} , poderá substituí-lo por xargs -i , pois é a abreviação.

O sh -c dirá ao seu bash / shell para ler o próximo comando de uma string e não da entrada padrão. Portanto, escrever sh -c "echo something" é equivalente a echo something .

O xargs -I {} sh -c "echo {}" lerá a entrada criada com sh -c , que é echo {} . Desde que você disse para substituir {} com os argumentos que você obteve do pipe, é o que acontecerá.

Você pode facilmente testar isso mesmo sem canalizar, basta digitar o comando acima em um terminal. Tudo o que você escrever em seguida será enviado para o terminal (Ctrl-D para sair).

No comando ls -la {} , a mesma coisa acontece novamente. O {} é substituído pelo conteúdo do comando pré-pipe.

    
por 22.03.2018 / 17:22