como enviar a saída do find para outro find

2

Ao pesquisar como fazer find ordenar os arquivos encontrados com base na hora da modificação, encontrei esta resposta , que fornece o seguinte encantamento:

find . -type f -printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //' | head -n 10

O problema acima é que eu não consigo memorizá-lo e não consigo encontrar uma maneira de empacotá-lo como um script de shell para que eu possa alimentá-lo com minha própria invocação de find onde eu terei a opção de aplicar os argumentos que eu quiser. Por exemplo. Como posso empacotar os itens acima na forma de um script de shell " showLatest " para que eu possa fazer coisas como as seguintes?

find src -type f -iname \*.py | showLatest 10
    
por Marcus Junius Brutus 20.11.2013 / 19:57

3 respostas

1

Este script funciona para mim:

#!/bin/bash
#
while IFS= read -r line; do
  find "$line" -printf '%T@ %p\n'
done | sort -k 1nr | sed 's/^[^ ]* //' | head -n 10

você pode canalizar seu find através dele:

(0)asus-romano:~/tmp% find . -type f | ./script11.sh
./script11.sh
./script10.sh
[...]

Em zsh , você poderia usar um alias global, que é muito mais rápido, mas acho que bash não os possui:

(0)asus-romano:~/tmp% alias -g showlast10="-printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //' | head -n 10"
(0)asus-romano:~/tmp% find . -type f showlast10
./script11.sh
./script10.sh
./Just  tab.xyz
[...]
    
por 20.11.2013 / 22:04
2

Em zsh, showLatest 10 é (om[1,10]) no final do padrão. Estes são os qualificadores da glob ; om classifica por tempo de modificação (o mais novo primeiro) e [1,10] seleciona os primeiros 10 resultados.

find src -type f -iname \*.py é print -lr src/**/(#i)*.py(D.) (você precisa executar setopt extended_glob primeiro, coloque isso em ~/.zshrc ).

O sinalizador de globbing . filtra somente arquivos regulares, D inclui arquivos e arquivos ocultos em diretórios ocultos, como o find versão faria. (#i) é um sinalizador globbing que torna o restante do padrão insensível a maiúsculas e minúsculas.

print -lr imprime seus argumentos, um por linha (que print -lr -- se o primeiro argumento pode começar com um traço). Combinando os dois, para obter os arquivos mais recentes:

print -lr src/**/(#i)*.py(D.om[1,10])

que, na prática, você pode encurtar para print -lr src/**/*.py(om[1,10]) .

Em zsh, você provavelmente não precisará disso, porque pode classificar a lista de arquivos quando a obtiver, pelo menos se eles estiverem vindo de um único padrão. Aqui está uma maneira de implementar showLatest em zsh que funciona com uma lista arbitrária de arquivos. Infelizmente, o qualificador om glob só pode ser aplicado a um único padrão, e um único padrão pode corresponder apenas a arquivos em um único diretório ou árvore. Um truque para ignorar isso é usar o qualificador de glob e (ou + ) para injetar uma lista arbitrária em um resultado de correspondência. Em seguida, aplique um qualificador o glob para executar a classificação; Qualificadores integrados não agem no resultado da e / + reescrita, mas os personalizados ( oe ou o+ ) do (a partir do zsh 5.0.5).

#!/usr/bin/env zsh
zmodload zsh/stat
files=("${(@f)$(<&0)}")
print -lr .(e\''reply=($files)'\'noe\''stat -A REPLY +mtime -- $REPLY'\')
    
por 21.11.2013 / 01:11
1

Primeiro, certamente é possível escrever um script como showLatest , provavelmente usando find nele. Mas então cada arquivo teria que ser analisado duas vezes.

Portanto, embora isso não responda à pergunta feita no final, ele deve resolver o problema descrito primeiro. Ou seja, como alimentar uma lista de parâmetros flexíveis para encontrar.

sfind.sh:

#!/bin/bash
find "${@:1:$[$#-1]}" -printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //' | head -n ${@:$#:1}

A invocação geral é sfind.sh [find-parameters] count . Para o exemplo dado, seria sfind.sh src -type f -iname \*.py 10

Explicação:

  • $@ contém a lista de parâmetros passada para o script
  • $# é o tamanho de $ @
  • ${@:1:$[$#-1]} todos os parâmetros, exceto o último
  • ${@:$#:1} o último parâmetro
por 20.11.2013 / 22:24

Tags