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'