Como verificar um arquivo com nome numérico e, se existir, copiá-lo com um novo nome usando o próximo número sequencial

Como verificar um arquivo com nome numérico e, se existir, copiá-lo com um novo nome usando o próximo número sequencial

Primeiramente quero pedir desculpas pela minha falta de conhecimento; este é literalmente meu primeiro script bash e meu conhecimento sobre Linux é basicamente inexistente. Respostas explicativas seriam muito apreciadas; Eu gostaria de aprender o porquê e não apenas o como.

Estou tentando escrever um script para automatizar um processo tedioso que precisa ser feito várias vezes ao dia. Resumindo, este script deve preparar um conjunto de arquivos com base em determinados requisitos. O script deve mover um arquivo de modelo e atribuir-lhe um número de versão ou copiar um arquivo existente usando um novo número de versão, com base no que for encontrado dentro de um diretório específico (por exemplo, criar se estiver vazio, copiar se houver algo lá).

Como exemplo, o arquivo pode ser nomeado

AAAAMMDD_##_username_testfile.json

onde o ## (número da versão) deve ser 01 para a primeira criação, depois 02 para a cópia, 03 para a cópia depois disso, etc. Um único diretório pode conter mais de 10 desses arquivos, todos com datas diferentes e sequenciais números de versão, bem como outros arquivos usando o mesmo formato, mas terminando em algo diferente de testfile.json

Não consigo encontrar uma maneira de fazer com que o script procure no diretório "test" o arquivo que termina em testfile.json que tem o número de versão mais alto e, se encontrado, extraia o número da versão como uma variável/parâmetro que posso passar de volta à sequência cp.

Neste ponto, nem tenho certeza de qual comando usar; a internet oferece de tudo, desde grep a awk, listagem e classificação... minha cabeça está girando!

Qualquer ajuda seria apreciada. Removi todas as informações de identificação. Informe-me se precisar de mais informações.

Responder1

Vamos dividi-lo em várias etapas.

Vamos escrever uma função que retornará o próximo número. Vamos buscar a simplicidade, em vez da eficiência máxima

Você precisa dar um nome de diretório

Você precisa fornecer a testfile.jsonparte do nome do arquivo

Precisamos encontrar todos os arquivos nesse diretório que terminam com esse final.

Os parâmetros são passados ​​para uma função usando $1, $2 etc.

getnum(){
  ls "$1" | grep "$2\$"
}

Use cut para retirar apenas o segundo campo, usando _como delimitador. (Observe que se eu fosse fazer isso, usaria sed em vez de grep e cut, outros poderiam usar awk, mas buscamos simplicidade aqui).

getnum() {
 ls "$1" | grep "$2\$" | cut -d_ -f 2
}

Use sort para classificá-los numericamente

getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n
}

Use head para obter apenas o primeiro valor

 getnum() {
  ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1
 }

Conclua isso para obtermos o valor em uma variável local

getnum() {
      local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
}

Se não houvesse valores, defina o valor antigo como 0. Imprima um número de 2 dígitos que seja um a mais que o antigo.

 getnum() {
  local oldnum=$(ls "$1" | grep "$2\$" | cut -d_ -f 2 | sort -n | head -1)
  if [ "$oldnum" = "" ]
  then
      oldnum=0
  fi
  printf "%02d\n" $(($oldnum+1))
 }

Observe que eu poderia ter omitido o teste para que oldnum não estivesse definido, como $((oldnum+1))seria expandido $((+1))nesse caso. Também posso usar expressões como $((${oldnum:-0}+1)), consulte os manuais para mais informações.

Você poderia então usar uma função como esta

  dir=somewhere/logs
  ext=testfile.json
  cp template "$dir/$(date +%Y%m%d_)$(getnum "$dir" "$ext")_$USER_$ext"

informação relacionada