删除文件夹保留文件
在一级文件夹下删除子文件夹,但是保留子文件夹里的内容
Windows, Windows 10
在一级文件夹下删除子文件夹,但是保留子文件夹里的内容
Windows, Windows 10
下面是我的一个尝试(my approach)版本。
有几个小功能:
最后的-p的用途:在尝试中发现,无论是习惯或其他原因,比如“文档.docx”和“文档(copy-1).docx”两个不同文件同时存在。
如果使用默认策略的话,“文档.docx”的第二个重名文件,应该命名为“文档(copy-1).docx”,但是这个文件已经存在了,为了放置覆盖,会被命名为“文档(copy-2).docx”。结果是造成视觉的错觉。
使用-p,就可以在运行命令时自定义策略,比如“重复-”,这样同名文件就可以轻松区分:
比如“文档.docx"的重复文件会被命名为:“文档(重复-0).docx”,“文档(重复-1).docx”等,
而“文档(copy-1).docx”的重复文件会被命名为: “文档(copy-1)(重复-0).docx”和“文档(copy-1)(重复-1).docx”等等。
这个脚本也可以在github上获得,后续更新也会在github上:http://tinyurl.com/bde8uaxw 或者 https://goo.su/7XXW2P
#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Move all files in a folder and its subfolders to another folder
#
# Desciption:
# utilize find command to list all files, exclude folders, in folder A and then move to
# folder B, if there's a duplicate file exist, it trys to rename to a new files and then
# move.
#
# Optional Arguments:
# run it with option: -h
#
# VERSION: v 1.0
#
# History:
# 2024-02-28: support options:
# -h show help
# -o Overwrite existing or duplicate file in target folder B
# -a <folder A> Absolute path of source folder A
# -b <folder B> Absolute path of target folder B
# -p <string> Appendix adding to duplicate/existing filename
# default is "copy-"
# -d Delete Fodler A after all files moved, default is "No"
# -v Verbose mode
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# The MIT License (MIT)
# Copyright (C) Tony Liu 2024-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
append="copy-"
overwrite=false
deleteFolder=false
verboaseMode=false
ScriptName="$(basename "$0")"
showHELP()
{
/bin/cat << EOF
Move all files in folder A and its subfolder(s) to another folder B
Usage: $ScriptName [-h] [-o|-d|-v] -a <folder> -b <folder> [-p <string>]
-h Show this help
-o Overwrite existing file
-a <folder A> FQP (Fully Qualified Path or absolute path) of source folder A
-b <folder B> FOP (fully qualified path or absolute path) of target folder B
-p <string> Appendix adding to duplicate/existing filename
default is "copy-"
-d Delete Fodler A after all are moved, default is "No"
-v Verbose mode
EOF
exit 0
}
moveFile()
{
local sourFile="$1"
local destFolder="$2"
filename="$(basename "$sourFile")"
[ "$filename" = "." ] && return
[ "$filename" = ".." ] && return
fName="${filename%.*}"
eName="${filename##*.}"
[ "$filename" = "$fName" ] && eName=""
[ -z "$fName" ] && [ -z "$eName" ] && return
if [ -z "$fName" ]; then fName=".$eName"; eName=""; fi
[ -n "$eName" ] && eName=".${eName}"
[ "${filename:0-1}" = "." ] && eName="."
local dupName=""
if ! $overwrite; then
if [ -e "${destFolder}/${fName}${eName}" ]; then
local i=0
while true; do
dupName="(${append}${i})"
[ -e "${destFolder}/${fName}${dupName}${eName}" ] || break
(( i++ ))
done
fi
fi
[ $verboaseMode ] && echo "moving [$sourFile] to [${destFolder}/${fName}${dupName}${eName}]"
mv -f "$sourFile" "${destFolder}/${fName}${dupName}${eName}"
}
while getopts "ha:A:b:B:p:odv" opt; do
case $opt in
h)
showHELP
;;
a|A)
sourFolder="$OPTARG"
;;
b|B)
destFolder="$OPTARG"
;;
p)
append="$OPTARG"
;;
o)
overwrite=true
;;
d)
deleteFolder=true
;;
v)
verboaseMode=true
;;
*)
showHELP
;;
esac
done
[ -z "$destFolder" ] && showHELP
[ -z "$sourFolder" ] && showHELP
[ -d "$sourFolder" ] || showHELP
[ -d "$destFolder" ] || mkdir "$destFolder"
find "$sourFolder" -type f -print0 | while read -r -d '' eachFile; do
moveFile "$eachFile" "$destFolder"
done
if $deleteFolder; then
echo "deleting folder A: [$sourFolder]"
rm -fr "$sourFolder"
fi
下面是我的一个尝试(my approach)版本。
有几个小功能:
最后的-p的用途:在尝试中发现,无论是习惯或其他原因,比如“文档.docx”和“文档(copy-1).docx”两个不同文件同时存在。
如果使用默认策略的话,“文档.docx”的第二个重名文件,应该命名为“文档(copy-1).docx”,但是这个文件已经存在了,为了放置覆盖,会被命名为“文档(copy-2).docx”。结果是造成视觉的错觉。
使用-p,就可以在运行命令时自定义策略,比如“重复-”,这样同名文件就可以轻松区分:
比如“文档.docx"的重复文件会被命名为:“文档(重复-0).docx”,“文档(重复-1).docx”等,
而“文档(copy-1).docx”的重复文件会被命名为: “文档(copy-1)(重复-0).docx”和“文档(copy-1)(重复-1).docx”等等。
这个脚本也可以在github上获得,后续更新也会在github上:http://tinyurl.com/bde8uaxw 或者 https://goo.su/7XXW2P
#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Move all files in a folder and its subfolders to another folder
#
# Desciption:
# utilize find command to list all files, exclude folders, in folder A and then move to
# folder B, if there's a duplicate file exist, it trys to rename to a new files and then
# move.
#
# Optional Arguments:
# run it with option: -h
#
# VERSION: v 1.0
#
# History:
# 2024-02-28: support options:
# -h show help
# -o Overwrite existing or duplicate file in target folder B
# -a <folder A> Absolute path of source folder A
# -b <folder B> Absolute path of target folder B
# -p <string> Appendix adding to duplicate/existing filename
# default is "copy-"
# -d Delete Fodler A after all files moved, default is "No"
# -v Verbose mode
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# The MIT License (MIT)
# Copyright (C) Tony Liu 2024-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
append="copy-"
overwrite=false
deleteFolder=false
verboaseMode=false
ScriptName="$(basename "$0")"
showHELP()
{
/bin/cat << EOF
Move all files in folder A and its subfolder(s) to another folder B
Usage: $ScriptName [-h] [-o|-d|-v] -a <folder> -b <folder> [-p <string>]
-h Show this help
-o Overwrite existing file
-a <folder A> FQP (Fully Qualified Path or absolute path) of source folder A
-b <folder B> FOP (fully qualified path or absolute path) of target folder B
-p <string> Appendix adding to duplicate/existing filename
default is "copy-"
-d Delete Fodler A after all are moved, default is "No"
-v Verbose mode
EOF
exit 0
}
moveFile()
{
local sourFile="$1"
local destFolder="$2"
filename="$(basename "$sourFile")"
[ "$filename" = "." ] && return
[ "$filename" = ".." ] && return
fName="${filename%.*}"
eName="${filename##*.}"
[ "$filename" = "$fName" ] && eName=""
[ -z "$fName" ] && [ -z "$eName" ] && return
if [ -z "$fName" ]; then fName=".$eName"; eName=""; fi
[ -n "$eName" ] && eName=".${eName}"
[ "${filename:0-1}" = "." ] && eName="."
local dupName=""
if ! $overwrite; then
if [ -e "${destFolder}/${fName}${eName}" ]; then
local i=0
while true; do
dupName="(${append}${i})"
[ -e "${destFolder}/${fName}${dupName}${eName}" ] || break
(( i++ ))
done
fi
fi
[ $verboaseMode ] && echo "moving [$sourFile] to [${destFolder}/${fName}${dupName}${eName}]"
mv -f "$sourFile" "${destFolder}/${fName}${dupName}${eName}"
}
while getopts "ha:A:b:B:p:odv" opt; do
case $opt in
h)
showHELP
;;
a|A)
sourFolder="$OPTARG"
;;
b|B)
destFolder="$OPTARG"
;;
p)
append="$OPTARG"
;;
o)
overwrite=true
;;
d)
deleteFolder=true
;;
v)
verboaseMode=true
;;
*)
showHELP
;;
esac
done
[ -z "$destFolder" ] && showHELP
[ -z "$sourFolder" ] && showHELP
[ -d "$sourFolder" ] || showHELP
[ -d "$destFolder" ] || mkdir "$destFolder"
find "$sourFolder" -type f -print0 | while read -r -d '' eachFile; do
moveFile "$eachFile" "$destFolder"
done
if $deleteFolder; then
echo "deleting folder A: [$sourFolder]"
rm -fr "$sourFolder"
fi
cd A
cat << \EOF > remove_dir.sh
#!/bin/bash
for item in $(ls -a); do
if [ -d ${item} ] && [ ${item} != "." ] && [ ${item} != ".." ]; then
for file in $(ls -a ${item}); do
if [ ${file} != "." ] && [ ${file} != ".." ]; then
mv "${item}/${file}" "${file}_${item}"
fi
done
rmdir ${item}
fi
done
EOF
chmod +x remove_dir.sh
./remove_dir.sh
完整的帶衝突檢測的版本
cd A
mv */* .*/* */.* .*/.* .
rmdir * .*
这个手动的话,可以设置方达的设置中,选择将文件夹置顶,这样就方便自己手动把文件夹拖拽出来了。当然,这个选项在低版本的macOS系统中是没有的,应该是至少Ventura以上的都有吧。
使用快捷方式或者自动化或者脚本都可以做到,但是需要讲清楚,是不是需要把某个文件夹里面的左右子文件夹都保留下来后,把这个文件夹本身删除,无论里面是否有其它的文件。
1.选择将文件夹置顶,这样就方便自己手动把文件夹拖拽出来了。➡️这个意思是还需要手动拖拽吗,如果量大有没有更省事的方法
2.求求自动化或脚本的解决方案,如何循环动作来保留A文件夹下n个子文件夹中的文件,但要把n个子文件夹删除。
题主的需求中没有这么具体的要求。
如果是需要处理大量的数据,使用自动化或者脚本,的确才是适应需求的解决方法之一,普通情况根本用不到。
如果有其它人有现成的最好。等我有时间上传上来个beta版本。
如果这个星期内没有看见上传,回复这个回答,我会收到提醒的email。
重复文件会被覆盖
沒加-f, 會提示. 或者可以加上 -n 顯式拒絕覆蓋.
自動完成衝突迴避太麻煩了, 尤其是有多個同名文件的情況下.
除非套循環去加前綴或者後綴.
👍短小精干👍,体现了脚本的精髓🤗!
删除文件夹保留文件