Gera automaticamente o nome do arquivo usando o bash

2

Vamos supor que eu tenha esses arquivos:

out-1.avi

Eu quero ter um código bash que me dará o próximo nome de arquivo para essa lista:

out-1.avi
out-2.avi
out-3.avi
etc.

Editar O que eu preciso fazer é obter o próximo nome de arquivo para o script de gravação da webcam, para que não ocorra a escrita!

    
por thekiwi5000 01.12.2014 / 22:10

5 respostas

4

Eu não sei o contexto, mas o loop a seguir contém todos os elementos que você precisará: -

n=0; while (($n < 10)); do ((++n)); echo name=out-$n.avi; done

Isso listará os 10 primeiros arquivos da sua sequência.

Após a sua edição, vejo várias respostas.

Uma simples modificação do meu loop original seria: -

n=1; while [ -f out-$n.avi ]; do ((++n)); done; echo name=out-$n.avi

Isso funcionará bem para alguns arquivos, mas se tornará cada vez mais ineficiente à medida que o número de arquivos for chegando às centenas.

Uma resposta mais eficiente seria salvar o número de arquivo mais recente em seu próprio arquivo: -

n='line<avicount.text'; ((++n)); echo "$n">avicount.text; echo name=out-$n.avi

Esse script gerará um novo nome toda vez que for chamado, mas depende do avicount.text restante sempre em sincronização com os arquivos e nomes em uso.

Uma solução melhor seria usar um registro de data e hora em vez de um número de seqüência: -

echo name=out-'date +%Y%M%d%H%m%S'.avi

Isto dará um nome único baseado no segundo quando o script for chamado, e pode ser útil ter o tempo de criação de um arquivo incluído em seu nome. Esse esquema também permite que arquivos sejam excluídos, arquivados ou movidos à vontade, sem afetar nomes de arquivos futuros.

    
por 01.12.2014 / 22:33
1
#!/bin/bash
LAST=$(find . -maxdepth 1 -name "*.avi" -type f -printf "%p\n" | sed -e s/.\/out-//g -e s/.avi//g | sort -g | tail -1)
touch out-$(($LAST + 1)).avi
  • A primeira linha seleciona o último arquivo avi modificado no diretório (sem recursiva) e extrai o número em seu nome.
  • A segunda linha adiciona 1 ao nome anterior e gera o arquivo.
por 02.12.2014 / 01:05
0

Você pode usar seq para gerar os valores e, em seguida, touch para criar os arquivos.

for n in $(seq 1 5)
do
    touch out-${n}.avi
done
    
por 01.12.2014 / 23:26
0

Supondo que você não tenha muitos arquivos no diretório de vídeo (nesse caso, essa abordagem não é muito eficiente), essa simples paz de código pode ajudar:

MAX=1000;
PREFIX="out-"
SUFFIX=".avi"

for i in 'seq 1 $MAX' ; do
    file="${PREFIX}${i}${SUFFIX}"

    if [ ! -e $file ] ; then
        break;
    fi
done

# this is the next available file name
echo $file

Observe que esse script preencherá todas as descontinuidades na ordem dos arquivos, portanto, se você estiver preocupado com uma ordem precisa ou talvez queira considerar uma opção para excluir arquivos "desnecessários" da sequência, convém usar mais abordagem sofisticada.

    
por 02.12.2014 / 01:40
0

A solução @jherran fornecida deve atender às suas necessidades. Se você quiser apenas que o script forneça o próximo nome de arquivo, em vez de criá-lo para você, altere "tocar" para "echo" no final do script.

No entanto, isso ficará mais lento e lento à medida que você adicionar muitos arquivos. Se você tiver necessidade de números seqüenciais, pode simplesmente escrever o número atual em um arquivo, depois lê-lo de volta antes de escrever o próximo arquivo, escrever o novo número e escrever o arquivo. Eu forneci código de exemplo para fazer isso abaixo.

No entanto, se você não precisar de números sequenciais e quiser apenas nomes de arquivos que não colidam, os carimbos de data serão bastante úteis. Eles classificam como você esperaria, e se você não viajar no tempo, estão aumentando monotonicamente.

Para uma resposta à pergunta que você fez (shell script para retornar o próximo valor) com base na minha sugestão acima de apenas usar um arquivo de contador, aqui está:

#!/usr/bin/sh

if [ -f counter.txt ]; then
{
   VAL='cat counter.txt'
   echo "out-$VAL.avi"
   VAL='expr $VAL + 1'
   echo "$VAL" > counter.txt
   exit 0
}
fi
echo "out-1.avi"
echo "2" > counter.txt
exit 0

Ou, se você quiser ir com a minha sugestão de data-selos para exclusividade e ordenação, basta ter o seu programa de gravação de arquivo pegar a saída deste comando:

 date +%F-%T

ou qualquer granularidade de datas e horas que você achar útil. O texto acima vai lhe dar algo parecido com isto:

2014-12-01-16:41:33

Coloque um ".avi" no final e você terá nomes de arquivos com timestamp, até o segundo.

    
por 02.12.2014 / 01:53