Определение наличия папки и переименование по шаблону

Я снова с другим вопросом о сценарии командной строки:)

Я сделал вспомогательный сценарий, который выглядит следующим образом

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...'

Это довольно простой, но он отражает мою точку зрения - это сохраняет последние два клона и создает новый, мне нужно сохранить мой последний клон в папке target, потому что я поставил ссылку на исходную папку в своем проекте затмения, чтобы указать туда: D

Я хотел бы сделать улучшение этого скрипта - вместо переименования target.bak -> target.old_bak и target -> target.bak я бы хотел, чтобы произошло следующее:

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

Так что на случай, если я прошел 6 клонов, и я клонирую для седьмого время, когда я хотел бы, чтобы это произошло:

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'... 

Это сообщество очень помогло мне с моим предыдущим массовым вопросом, поэтому я надеюсь, что вы будете достаточно полезны, чтобы предоставить мне достойный способ сделать это как well:)

РЕДАКТИРОВАТЬ:

Окончательный вариант сценария выглядит следующим образом, спасибо Wolfie за ваш большой вклад.

#!/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...'
2
задан 27 May 2013 в 17:52

2 ответа

Это могло помочь Вам:

Поскольку это регистрирует:

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

Можно сделать это:

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

Для target -> target.bak0 просто сделайте cp target target.bak

Обновление:

Я протестировал эту команду и работы только от 0-> 19 резервного копирования, чем сбои переименования..., но для то, в чем Вы нуждаетесь, в порядке :)

Обновление № 2:

Версия сценария:

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

Пример:

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

Попробуйте этим..., но имейте в виду, что это - только пример кода для "производства", необходимо добавить некоторую проверку прежде, чем выполнить это :)

Эта версия работает с N bak файлы... не только 19 ;)

2
ответ дан 27 May 2013 в 17:52

Я обычно отговариваю от использования ls в программе (объяснение здесь), но это кажется простым, таким образом:

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

Примечания:

  • использовать command избегать любых псевдонимов или функций для ls
  • используйте ls's -v опция гарантировать файлы отсортирована "численно"
    • т.е. столь "целевой bak10" следует за "целью bak9", не "целью bak1"
2
ответ дан 27 May 2013 в 17:52

Другие вопросы по тегам:

Похожие вопросы: