
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.json
parte 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"