No Bash, gostaria de criar uma função que retorne o nome do arquivo do arquivo mais recente que corresponde a um determinado padrão. Por exemplo, eu tenho um diretório de arquivos como:
Directory/
a1.1_5_1
a1.2_1_4
b2.1_0
b2.2_3_4
b2.3_2_0
Eu quero o arquivo mais recente que começa com 'b2'. Como faço isso no bash? Eu preciso ter isso no meu ~/.bash_profile
script.
Respostas:
O
ls
comando possui um parâmetro-t
para classificar por tempo. Você pode pegar o primeiro (mais novo) comhead -1
.Mas cuidado: por que você não deve analisar a saída de ls
Minha opinião pessoal: a análise
ls
só é perigosa quando os nomes de arquivos podem conter caracteres engraçados, como espaços ou novas linhas. Se você pode garantir que os nomes dos arquivos não contenham caracteres engraçados, a análisels
é bastante segura.Se você estiver desenvolvendo um script que deve ser executado por muitas pessoas em muitos sistemas em muitas situações diferentes, recomendo não analisar
ls
.Aqui está como fazê-lo "certo": Como posso encontrar o arquivo mais recente (mais recente, antigo e antigo) em um diretório?
fonte
ls
,printf "%s\n" b2* | head -1
fará isso por você.b2.10_5_2
esta solução é eliminada.A combinação
find
els
funciona bem paraA solução:
Vamos dividir:
Com
find
nós podemos combinar todos os arquivos interessantes como este:usando
-print0
, podemos passar todos os nomes de arquivos com segurança para ols
seguinte:find
parâmetros e padrões de pesquisa adicionais podem ser adicionados aquils -t
classificará os arquivos pela hora da modificação (mais recentes primeiro) e os imprimirá um em uma linha. Você pode usar-c
para classificar por hora de criação. Nota : isso será interrompido com nomes de arquivos contendo novas linhas.Finalmente,
head -1
obtemos o primeiro arquivo na lista classificada.Nota:
xargs
use limites do sistema para o tamanho da lista de argumentos. Se esse tamanho exceder,xargs
chamaráls
várias vezes. Isso interromperá a classificação e provavelmente também a saída final. Correpara verificar os limites do seu sistema.
Nota 2: use
find . -maxdepth 1 -name "my-pattern" -print0
se você não deseja pesquisar arquivos através de subpastas.Nota 3: Como apontado pelo @starfry - o
-r
argumento forxargs
está impedindo a chamada dels -1 -t
, se nenhum arquivo foi correspondido pelofind
. Obrigado pela sugestão.fonte
find . -name "my-pattern" ... -print0
me dáfind: paths must precede expression: `...'
...
significa "mais parâmetros". Apenas o omita, se você não precisar.-r
à linha de comando xargs que diz ao xargs para não executar sua linha de comando se não receber nada em sua entrada padrão.-r
à resposta.Esta é uma possível implementação da função Bash necessária:
Ele usa apenas os recursos internos do Bash e deve lidar com arquivos cujos nomes contenham novas linhas ou outros caracteres incomuns.
fonte
nullglob_shopt=$(shopt -p nullglob)
e depois$nullglob
colocar de voltanullglob
como era antes.$()
ou backticks) porque é lento, principalmente no Cygwin, mesmo quando o comando usa apenas recursos internos. Além disso, o contexto do subshell no qual os comandos são executados às vezes pode fazer com que eles se comportem de maneiras inesperadas. Também tento evitar o armazenamento de comandos em variáveis (comonullglob_shopt
) porque coisas muito ruins podem acontecer se você errar o valor da variável.cat
!'. Mesmo que isso dê mais trabalho, tem o benefício de mostrar os conceitos das pessoas. Tenha um +1!Nomes de arquivos incomuns (como um arquivo que contém o
\n
caractere válido podem causar estragos nesse tipo de análise. Aqui está uma maneira de fazer isso no Perl:Essa é uma transformação schwartziana usada lá.
fonte
Você pode usar
stat
com um arquivo glob e um decorate-sort-undecorate com o tempo do arquivo adicionado na frente:fonte
stat
, se eu estiver lembrando suas opções corretamente. Para obter resultados semelhantes em outras plataformas, você pode usarstat -c $'%Y\t%n' b2* | sort -rn | head -n1 | cut -f2-
Encantamento de funções de magia negra para aqueles que desejam a
find ... xargs ... head ...
solução acima, mas em formato de função fácil de usar, para que você não precise pensar:Impressões:
Qual é:
O nome do arquivo com o registro de data e hora modificado mais antigo do arquivo no diretório especificado, que corresponde ao padrão especificado.
fonte
Use o comando find.
Supondo que você esteja usando o Bash 4.2 ou superior, use
-printf '%T+ %p\n'
o valor do registro de data e hora do arquivo.Exemplo:
Para um script mais útil, consulte o script find-latest aqui: https://github.com/l3x/helpers
fonte
Existe uma maneira muito mais eficiente de conseguir isso. Considere o seguinte comando:
Este comando localiza o arquivo mais recente produzido exatamente há um minuto com a pesquisa curinga em "b2 *". Se você deseja arquivos dos últimos dois dias, será melhor usar o comando abaixo:
O "." representa o diretório atual. Espero que isto ajude.
fonte