Bash scripting para criar o próximo arquivo mais alto

4

Minha tarefa é escrever um script que crie o próximo arquivo mais alto em um determinado diretório. Eu consegui classificar os arquivos no diretório para que o script produza o nome de arquivo mais alto. Por exemplo, dos arquivos red_01 red_02 red_03 , ele gera red_04

Minha próxima tarefa é criar o arquivo mais alto. Como posso criar o arquivo red_04 ? Preciso armazenar o número em uma variável e incrementá-lo de alguma forma?

    
por Ria 27.06.2017 / 11:06

4 respostas

2

Isso fará o que você precisa. Ajuste os caminhos para qualquer caminho que você precisar, use variáveis e analise-os no script. Mas sim, você pode ajustar você mesmo;)

#!/bin/bash
#count your existing files
NUMBERATM='find ./ -type f -name "red_*" | wc -l'
#add +1 to create the next higher file
NUMBERATM=$((NUMBERATM+1))

#check if it's below 10 since you need the 0 infront of it
if [ $NUMBERATM -lt "10" ]; then
   var=0$NUMBERATM
else
   var=$NUMBERATM
fi

#create your file
touch red_$var
    
por Ziazis 27.06.2017 / 11:25
3

Sem analisar ls ou find output e sem criar nenhum arquivo extra, incrementando apenas o nome do último arquivo (os outros arquivos podem ter nomes).

Para contar arquivos em um diretório:

stat * --printf "%i\n" | wc -l

Para obter o último arquivo:

i=0; j=$(stat * --printf "%i\n" | wc -l); for k in *; do (( (j - ++i) < 1 )) && echo "$k"; done

(( (j - ++i) < 1 )) testa quantas vezes o loop foi executado e o compara ao número de arquivos no diretório. Ele se baseia no fato de que for faz um loop sobre os arquivos de uma forma ordenada.

Para obter o nome do próximo arquivo, assumindo o padrão name_{01..99}

i=0
j=$(stat * --printf "%i\n" | wc -l)
for k in *; do 
  (( (j - ++i) < 1 )) && 
  echo "${k%%_*}"_$(printf %02d "$(( ${k##*_} + 1 ))")
done

Para criar o arquivo:

touch $(i=0; j=$(stat * --printf "%i\n" | wc -l); for k in *; do (( (j - ++i) < 1 )) && echo "${k%%_*}"_$(printf %02d "$(( ${k##*_} + 1 ))"); done)

ou

touch $(
  i=0
  j=$(stat * --printf "%i\n" | wc -l)
  for k in *; do 
    (( (j - ++i) < 1 )) &&
    echo "${k%%_*}"_$(printf %02d "$(( ${k##*_} + 1 ))")
  done
)
    
por Zanna 27.06.2017 / 11:54
2

Faça um loop pelos números e verifique se o arquivo já existe. Se existir, continue com o loop; Se o arquivo não existir, crie-o.

for n in $(seq -w 01 99); do
    [[ ! -f "red_${n}" ]] && { touch "red_${n}"; break; }
done

Altere para $(seq -w 001 999) ou mais dígitos, se necessário.

Nota: Isso criará red_02 se estiver faltando, mesmo que red_01 e red_03 existam.

    
por RoVo 27.06.2017 / 11:39
2

Isso funciona mesmo se houver lacunas e evento se os números não forem preenchidos em nomes de arquivos

#!/bin/bash

highest=-1
IFS="   
"
for f in red_*; do
    num=$(echo $f| cut -d _ -f2)
    if [[ ! "$f" =~ red_[0-9]{1,2} ]];then #prevents failing because of                                
                                      #spaces or letters
        num=0
    else
        num=$(printf %d "$((10#$num))"); #eliminate zero padding to prevent 
                                         #interpretation as octal
    fi

    if [[ $num -gt "$highest" ]];then
        highest=$num
    fi
done

newfile=red_$(printf %02d $(($highest+1)))
echo $newfile
touch $newfile

-

Você pode receber tanto o prefixo quanto a quantidade desejada de preenchimento zero na saída como parâmetros, eliminando os literais "red_" e "02".

    
por Tulains Córdova 27.06.2017 / 15:14