Eu posso selecionar um arquivo aleatório usando este comando
find ./ -type f | shuf -n 1
Mas está mostrando o mesmo arquivo algumas vezes.
É possível parar de escolher arquivos duplicados?
Existe algum outro utilitário para esta tarefa?
Eu tenho cerca de 50 mil arquivos txt em uma pasta que pode ter subpastas recursivas e quero escolher um arquivo aleatório para vê-lo e não quero vê-lo novamente + há novos arquivos adicionados à pasta todos os dias ...
O problema com seu código é que você está gerando novamente a lista toda vez para escolher um novo nome de caminho. Isso potencialmente forneceria os mesmos nomes de caminho repetidamente, desde que você mantivesse os mesmos arquivos nos diretórios sobre os quais você gera a lista.
A resposta simples para o caso em que você ocasionalmente executa seu script é mover os arquivos do processo (ou excluí-los). Dessa forma, na próxima vez que você executar o script e gerar novamente a lista aleatória, os arquivos já processados não farão parte da lista.
Por exemplo, supondo que todos os arquivos estejam localizados dentro ou abaixo do diretório
$HOME/newfiles
, o seguinte selecionaria um arquivo e o moveria para$HOME/oldfiles
:O restante desta resposta é referente ao caso em que você deseja fazer um loop sobre nomes de caminhos aleatórios em uma e mesma invocação do script.
Supondo que seus arquivos e diretórios não contenham novas linhas incorporadas, isso mostra o que Jeff Schaller sugeriu em um comentário :
Isso lhe daria nomes de caminho aleatórios de arquivos regulares dentro ou abaixo do diretório atual, se, como mencionei, nenhum dos nomes de caminho na hierarquia contivesse novas linhas (nesse caso
shuf
, embaralharia esses nomes).Uma variante segura seria embaralhar a lista com uma lista terminada em nulo:
Este exemplo (e o próximo) é adaptado de https://unix.stackexchange.com/a/543188/116858
No
zsh
shell, você poderia fazerIsso funciona de maneira semelhante ao código acima com a diferença de que, como está usando um shell glob e nenhuma ferramenta de filtragem de texto orientada por linha, as novas linhas nos nomes dos arquivos não seriam um problema (e você não precisa passar listas terminadas em nul ).
O legal de fazer isso
zsh
é que você não precisa chamar nenhuma ferramenta externa.Se estou entendendo a pergunta corretamente, uma coisa que o OP pode fazer é embaralhar a lista em um arquivo (ou variável, se estiver em um
BASH
script) e extrair elementos dessa lista. Dessa forma, o OP não chamará o mesmo arquivo duas vezes até o final da lista completa.Por exemplo,
para criar a lista em um arquivo e chamá-la por meio de algo como,
Ou uma linha equivalente com
sed
ouawk
.Como alternativa, se tudo isso estiver sendo colocado em um
BASH
script, também é possível fazer algo assim:Que tal trabalhar apenas com o
inode
....Não importa se o
seen
arquivo está no seu caminho de pesquisa e, se estiver, basta adicionar o seu próprio arquivoinode
para ser excluído.Para uma única sessão de inspeção, basta percorrer a lista
Nota: A suposição é que os arquivos não são excluídos. Se eles forem e
inode
s forem reutilizados, eles terão que ser excluídos doseen
Depois de descobrir que
sed
copia e reescreve arquivos e altera oinode
para oseen
arquivo, essa abordagem fica mais complicada .... uma solução para o problema de exclusão pode ser usared
em vez desed
.Para excluir o arquivo
touch wood
aqui ele manterá o controle de arquivos embaralhados.
toda vez que usar
find
leva mais tempo... em vez disso, é melhor usar o utilitário mlocate aqui...desta forma
updatedb
procura novos ficheiros apenas em vez de voltar a verificar todos os ficheiros