No seu primeiro exemplo, grep
não deve reordenar os nomes de arquivos que você passa para ele. Se você os estiver passando explicitamente, ele imprimirá a saída na mesma ordem que a lista de arquivos que você passa. No entanto, se você está passando um caractere curinga, está correto que seu shell expandirá esse caractere curinga na ordem lexical (que é basicamente o que ls
usa como padrão).
Depois de analisar as outras sugestões, apresento o seguinte:
file='ls -t --quoting-style=shell "dir" | xargs grep -l "regex" | head -n 1'
Acho que isso atende aos seus requisitos e aborda as preocupações levantadas por outras pessoas da seguinte forma:
- Você pode usar
ls -t
sem -l
, portanto não há necessidade de analisar a saída de ls -l
com awk
ou cut
apenas para obter o nome do arquivo.
- Não inverta a ordem de classificação de
ls
. Usar ls -t
coloca os arquivos mais novos em primeiro lugar, e pegar o primeiro com head
causará um curto-circuito no pipeline assim que o primeiro arquivo correspondente for encontrado (assim você procura a lista mínima de arquivos necessários para encontrar uma correspondência).
- O piping para
xargs
efetivamente permite pesquisar um número ilimitado de arquivos sem executar o comprimento máximo da linha de comando, e faz isso sem loop.
- O uso de
ls --quoting-style=shell
fornece nomes de arquivos com aspas simples, conforme necessário, portanto, nomes de arquivos com espaços incorporados ou caracteres de controle são manipulados corretamente.
Por favor, note que --quoting-style
é uma extensão GNU e não é provável que funcione com um não-GNU ls
. Você deve estar bem no Linux. O seguinte é mais portátil, mas adiciona uma chamada a sed
para citar os nomes dos arquivos, portanto, há um pouco mais de sobrecarga:
file='ls -t "dir" | sed 's/\(.*\)/""/' | xargs grep -l "regex" | head -n 1'