我有一个包含许多文件的项目,位于多个子目录中。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
删除旧文件,即所有名为filename
和filename2
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"