我应该如何批量重命名文件来修复 Dropbox(false)检测到的“冲突”版本为“非冲突”版本?

我应该如何批量重命名文件来修复 Dropbox(false)检测到的“冲突”版本为“非冲突”版本?

我有一个包含许多文件的项目,位于多个子目录中。Dropbox 以某种方式将其中一些文件的最新版本替换为旧版本,并通过在 tmen 中添加“ (Johns in Konflikt stehende Kopie 2013-03-17).txt”重命名最新版本。

现在,我需要将所有带有该附加内容“ (Johns in Konflikt stehende Kopie 2013-03-17)”的文件重命名为原始文件名,并删除旧的“权威”版本(因为 Dropbox 看到了它们)。

是否有一个 shell 脚本或某些东西可以在终端中针对某个目录运行,它会在目标目录上递归执行此操作?

例如:“filename (Johns in Konflikt stehende Kopie 2013-03-17)”应重命名为“filename”,如果已经存在一个名为 filename 的文件,则先将其删除。

答案1

这对我有用:

while read -r i;
do
        old_file=${i%%(*}
        rm $old_file
        mv "$i" "$old_file"
done <<< "$(find | grep "2013-03-17)$")"

前:

./files/filename2 (Johns in Konflikt stehende Kopie 2013-03-17)
./files/filename2
./files/filename (Johns in Konflikt stehende Kopie 2013-03-17)
./files/filename
./files/subfolder/filename (Johns in Konflikt stehende Kopie 2013-03-17)
./files/subfolder/filename

后:

./files/filename 
./files/filename2 
./files/subfolder/filename 

进行备份以防万一。

解释:

while read -r i; <<< "$(find | grep "2013-03-17)$")"读取该命令输出的所有行,返回path/filename所有以2013-03-17)--结尾的文件您可能需要添加文件扩展名或仅获取文件名

old_file=${i%%(*}old_file将命令输出的字符串中的所有内容设置为find,即将filename (Johns in Konflikt stehende Kopie 2013-03-17)所有其他内容设置为 之前的所有内容(,即filename

rm $old_file删除旧文件,即所有名为filenamefilename2

mv "$i" "$old_file"重命名filename (Johns in Konflikt stehende Kopie 2013-03-17)filename

答案2

根据 Alex 的回答,我编写了一个脚本,让您以交互方式浏览冲突文件列表,并决定是否要使用 Dropbox 标记为冲突的副本来替换普通副本。

#!/bin/bash

counter=0
resolved=0
diffprompt=true 
mvprompt=true
mvall=false 
while read -r i
do
    if [ ! -f "$i" ]; then
        break;
    fi
    echo 
    echo "Found conflicted file:"
    echo "    $i"
    old_file=`echo "$i" | sed 's/ (.*)//g'`
    echo "    $old_file"
    if [ "$diffprompt" = true ]; then
        echo
        while true; do
            prompt1="Show diff between the two files [y/n]?"
            prompt2="press q to quit, r to stop diff prompts"
            read -p "...$prompt1 ($prompt2)" yn </dev/tty
            case $yn in
                [Yy]* ) diffuse "$i" "$old_file"; break;;
                [Nn]* ) break;;
                [Qq]* ) exit;;
                [Rr]* ) diffprompt=false; break;;
                * ) echo "Please answer yes or no.";;
            esac
        done
    fi

    if [ "$mvall" = true ]; then
        mv "$i" "$old_file"
    elif [ "$mvprompt" = true ]; then
        echo
        while true; do
            prompt3="Keep the conflicted version and"
            prompt4="overwrite the plain version [y/n]?"
            prompt5="press q to quit, r to stop mv prompts,"
            prompt6="a to move all files without prompting again"
            read -p "...$prompt3 $prompt4 ($prompt5 $prompt6)" yn </dev/tty
            case $yn in
                [Yy]* ) mv "$i" "$old_file"; resolved=$((resolved+1)); break;;
                [Aa]* ) mv "$i" "$old_file"; mvall=true; break;;
                [Nn]* ) break;;
                [Qq]* ) exit;;
                [Rr]* ) mvprompt=false; break;;
                * ) echo "Please answer yes or no.";;
            esac
        done
    fi
    counter=$((counter+1))
done <<< "$(find . -name '*(pmd-laptop*2014-08-06)*')"

# please note that my conflict device is called 'pmd-laptop'
# and that the date of the conflict is '2014-08-06'
# replace those in the find string according to your case

echo 
echo "Total number of conflicts = $counter"
echo "Conflicts resolved = $resolved"

相关内容