Detectando se a pasta existe e renomeando por padrão

2

Eu novamente com outra pergunta de script de linha de comando:)

Eu fiz um script auxiliar que se parece com isso

echo 'target.bak -> target.old_bak'
mv target.bak target.old_bak
echo 'target -> target.bak'
mv target target.bak
echo 'git clone:target -> target'
git clone ssh://Shark@mcs15:29418/our-trunk-target target
cd target
echo 'Managing hooks...'
scp -p -P 29418 Shark@mcs15:/hooks/commit-msg .git/hooks/
echo '... done. Enjoy the new clone while it lasts...'

Isso é bem básico, mas mostra o que quero dizer - ele mantém os dois últimos clones e cria um novo, preciso manter meu clone mais recente na pasta target , porque eu criei uma ligação simbólica com minha pasta de origem em meu projeto eclipse ponto lá: D

Gostaria de fazer uma melhoria neste script - em vez de renomear target.bak -> target.old_bak e target -> target.bak , gostaria que o seguinte ocorresse:

if bakN exists then rename bakN -> bak(N+1)
rename recursivelly bak(N-1) -> bakN
rename target to target.bak
clone new repo into target

Então, caso eu tenha passado por 6 clones e estou clonando pela sétima vez, eu gostaria que isso acontecesse:

target.bak4 -> target.bak5
target.bak3 -> target.bak4
target.bak2 -> target.bak3
target.bak1 -> target.bak2
target.bak0 -> target.bak1
target      -> target.bak0
Cloning into 'target'... 

Esta comunidade ajudou-me imensamente com a minha anterior pergunta sobre as diferenças de massa, por isso espero que você seja útil o suficiente para me proporcionar uma maneira decente de fazer isso também:)

EDITAR:

O script finalizado é assim, graças a Wolfie pelas suas principais contribuições.

#!/bin/bash
MYUSER="Shark"
TRUNK_FOLDER="target-on-trunk"
TARGET_FOLDER="target"

if [ -n "'ls -1d -v ${TARGET_FOLDER}.bak?'" ]; then
    echo "Pushing back numbered backups..."
    MAXBCK='ls -1d ${TARGET_FOLDER}.bak* 2>/dev/null | egrep -o "[0-9]+$" | sort -n | tail -n1'
    if [ "$MAXBCK" != "" ]; then
        for (( c=$MAXBCK; c>=0; c-- ))
            do
                mv -v ${TARGET_FOLDER}.bak$c ${TARGET_FOLDER}.bak$(($c+1))
        done
    fi
fi

if [ -e "$TARGET_FOLDER.bak" ]; then
        mv -v ${TARGET_FOLDER}.bak ${TARGET_FOLDER}.bak0
fi

if [ -e "$TARGET_FOLDER" ]; then
        mv -v ${TARGET_FOLDER} ${TARGET_FOLDER}.bak
fi

echo "git clone: ${TRUNK_FOLDER} -> ${TARGET_FOLDER}"
git clone ssh://${MYUSER}@mcs15:29418/${TRUNK_FOLDER} ${TARGET_FOLDER}
cd ${TARGET_FOLDER}
echo 'Managing hooks...'
scp -p -P 29418 ${MYUSER}@mcs15:/hooks/commit-msg .git/hooks/
echo '... done. Enjoy the new clone while it lasts...'
    
por Shark 27.05.2013 / 11:17

2 respostas

2

Isso pode ajudar você:

Para estes arquivos:

target.bak4 -> target.bak5
target.bak3 -> target.bak4
target.bak2 -> target.bak3
target.bak1 -> target.bak2
target.bak0 -> target.bak1

Você pode fazer isso:

ls -1 target.bak* | awk '{print "mv "$0" "substr($0,0,length)substr($0,length,1)+1}' | sh

Para target -> target.bak0 , basta fazer cp target target.bak

Atualização:

Eu testei este comando e funciona apenas de 0 - > 19 backup, que a renomeação falhar ... mas para o que você precisa está OK:)

Atualização nº 2:

Versão do script:

if [ $# != 1 ]; then
        echo 'Usage: $0 target'
        exit
fi
if [ 'ls -1 $1* 2>/dev/null | grep -c $1' -lt 1 ]; then
        echo "No file found"
        exit
fi

MAXBCK='ls -1 $1.bak* 2>/dev/null | egrep -o "[0-9]+$" | sort -n | tail -n1'

if [ "$MAXBCK" != "" ]; then
        for (( c=$MAXBCK; c>=0; c-- ))
        do
        #       echo $c $(($c+1))
                mv $1.bak$c $1.bak$(($c+1))
        done
fi

cp $1 $1.bak0

Exemplo:

wolfy@wolfy-ubuntu:~/tmp$ ll
total 4
-rwxr-xr-x 1 wolfy wolfy 402 May 27 14:43 fresh_clone.sh*
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:10 test
wolfy@wolfy-ubuntu:~/tmp$ ./fresh_clone.sh test
wolfy@wolfy-ubuntu:~/tmp$ ll
total 4
-rwxr-xr-x 1 wolfy wolfy 402 May 27 14:43 fresh_clone.sh*
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:10 test
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak0
wolfy@wolfy-ubuntu:~/tmp$ ./fresh_clone.sh test
wolfy@wolfy-ubuntu:~/tmp$ ll
total 4
-rwxr-xr-x 1 wolfy wolfy 402 May 27 14:43 fresh_clone.sh*
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:10 test
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak0
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak1
wolfy@wolfy-ubuntu:~/tmp$ ./fresh_clone.sh test
wolfy@wolfy-ubuntu:~/tmp$ ll
total 4
-rwxr-xr-x 1 wolfy wolfy 402 May 27 14:43 fresh_clone.sh*
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:10 test
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak0
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak1
-rw-r--r-- 1 wolfy wolfy   0 May 27 14:44 test.bak2

Tente com isso ... mas lembre-se de que este é apenas um código de exemplo, para "produção" você deve adicionar um cheque antes de executar isto:)

Esta versão funciona com arquivos N bak ... não apenas 19;)

    
por Wolfy 27.05.2013 / 11:41
2

Eu normalmente não recomendo usar ls em um programa ( justificativa aqui ), mas isso parece simples, então:

touch target.bak{0..10}   # for testing

base=target
bak="${base}.bak"
command ls -vr "$bak"* | while IFS= read -r file; do
    n=${file#$bak}
    echo mv "$bak$n" "$bak$((n+1))"
done
echo mv "$base" "${bak}0"
mv target.bak10 target.bak11
mv target.bak9 target.bak10
mv target.bak8 target.bak9
mv target.bak7 target.bak8
mv target.bak6 target.bak7
mv target.bak5 target.bak6
mv target.bak4 target.bak5
mv target.bak3 target.bak4
mv target.bak2 target.bak3
mv target.bak1 target.bak2
mv target.bak0 target.bak1
mv target target.bak0

Notas:

  • use command para evitar aliases ou funções para ls
  • use a opção -v de ls para garantir que os arquivos sejam classificados "numericamente"
    • , por exemplo, "target.bak10" segue "target.bak9", não "target.bak1"
por glenn jackman 27.05.2013 / 15:19