检测文件夹是否存在并按模式重命名

检测文件夹是否存在并按模式重命名

我又有另一个命令行脚本问题了:)

我制作了一个如下所示的辅助脚本

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文件夹中保留我的最新克隆,因为我在我的 eclipse 项目中将我的源文件夹符号链接到那里: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'... 

这个社区极大地帮助了我解决之前的质量差异问题,所以我希望你们也能帮我提供一个不错的方法来解决这个问题:)

编辑:

最终完成的脚本如下所示,感谢 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...'

答案1

这可以帮助您:

对于此文件:

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

我通常建议不要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 的-v选项确保文件按“数字”排序
    • 即“target.bak10”位于“target.bak9”之后,而不是“target.bak1”

相关内容