删除中间文件夹
deleting intermediary folders
也许你们中的某个人手头有这样的东西?我尝试在 windows 上使用 robocopy 但无济于事。我还尝试用 find 等在 linux 中编写一个 bash 脚本...但也放弃了 ^^ Google 搜索带来的不幸的是也没有解决方案。我的私人照片库需要这个。
解决方案可以基于 linux 或 windows,两者都可以。有任何想法吗?
我想摆脱数百个'intermediary folders'。
我将 'intermediary folder' 定义为只包含一个子文件夹的文件夹。例子
folder 1
file in folder 1
folder 2 <-- 'intermediary folder: contains exactly one sub-folder, nothing else'
folder 3
file in folder 3
我想结束的是:
folder 1
file in folder 1
folder 3
file in folder 3
我不需要递归脚本(一次删除几层中间文件夹),我会 运行 几次。
如果脚本可以将上面示例中的文件夹 3 重命名为 'folder 2 - folder 3',那就更酷了,但我想我可以在没有这个功能的情况下生活。
我想你们中的一位 linux 专家有一个方便的衬垫吗? ^^
非常感谢!
看看这段代码:
#!/usr/bin/env bash
shopt -s nullglob
while IFS= read -rd '' dir; do
f=("$dir"/*)
if ((${#f[@]}==1)) && [[ -d $f ]]; then
mv -t "${dir%/*}" "$f" || continue
rm -r "$dir"
fi
done < <(find folder1 -depth -mindepth 1 -type d -print0)
解释:
shopt -s nullglob
:允许不匹配任何文件的文件名模式扩展为空字符串
find ... -depth
:使得find
以深度优先的顺序遍历文件系统
find ... -mindepth 1
:处理除起点外的所有目录
find ... -type d
: 只查找目录
find ... -print0
:打印由空字符分隔的目录 [=18=]
(以正确处理文件名中可能的换行符)
while IFS= read ...
:遍历所有目录(find
的输出)
f=("$dir"/*)
: 在当前处理的目录 中创建一个包含所有文件的数组
((${#f[@]}==1)) && [[ -d $f ]]
:如果只有一个文件且是目录则为true
mv -t "${dir%/*}" "$f"
: 将唯一的子目录移动到上一级目录
mv ... || continue
: 如果子目录已经存在于上面的目录中,mv
可能会失败。 || continue
忽略此类子目录
rm -r "$dir"
: 删除处理后的目录
测试运行:
$ tree folder1
folder1
├── file1
├── folder2
│ └── folder3
│ └── file3
├── folder4
│ ├── file4a
│ ├── file4b
│ └── file4c
└── folder5
└── folder6
├── file6
└── folder7
└── folder8
└── folder9
├── dir9
└── file9
$ ./script
$ tree folder1
folder1
├── file1
├── folder3
│ └── file3
├── folder4
│ ├── file4a
│ ├── file4b
│ └── file4c
└── folder6
├── file6
└── folder9
├── dir9
└── file9
也许你们中的某个人手头有这样的东西?我尝试在 windows 上使用 robocopy 但无济于事。我还尝试用 find 等在 linux 中编写一个 bash 脚本...但也放弃了 ^^ Google 搜索带来的不幸的是也没有解决方案。我的私人照片库需要这个。
解决方案可以基于 linux 或 windows,两者都可以。有任何想法吗?
我想摆脱数百个'intermediary folders'。
我将 'intermediary folder' 定义为只包含一个子文件夹的文件夹。例子
folder 1
file in folder 1
folder 2 <-- 'intermediary folder: contains exactly one sub-folder, nothing else'
folder 3
file in folder 3
我想结束的是:
folder 1
file in folder 1
folder 3
file in folder 3
我不需要递归脚本(一次删除几层中间文件夹),我会 运行 几次。
如果脚本可以将上面示例中的文件夹 3 重命名为 'folder 2 - folder 3',那就更酷了,但我想我可以在没有这个功能的情况下生活。
我想你们中的一位 linux 专家有一个方便的衬垫吗? ^^
非常感谢!
看看这段代码:
#!/usr/bin/env bash
shopt -s nullglob
while IFS= read -rd '' dir; do
f=("$dir"/*)
if ((${#f[@]}==1)) && [[ -d $f ]]; then
mv -t "${dir%/*}" "$f" || continue
rm -r "$dir"
fi
done < <(find folder1 -depth -mindepth 1 -type d -print0)
解释:
shopt -s nullglob
:允许不匹配任何文件的文件名模式扩展为空字符串find ... -depth
:使得find
以深度优先的顺序遍历文件系统find ... -mindepth 1
:处理除起点外的所有目录find ... -type d
: 只查找目录find ... -print0
:打印由空字符分隔的目录[=18=]
(以正确处理文件名中可能的换行符)while IFS= read ...
:遍历所有目录(find
的输出)f=("$dir"/*)
: 在当前处理的目录 中创建一个包含所有文件的数组
((${#f[@]}==1)) && [[ -d $f ]]
:如果只有一个文件且是目录则为truemv -t "${dir%/*}" "$f"
: 将唯一的子目录移动到上一级目录mv ... || continue
: 如果子目录已经存在于上面的目录中,mv
可能会失败。|| continue
忽略此类子目录rm -r "$dir"
: 删除处理后的目录
测试运行:
$ tree folder1
folder1
├── file1
├── folder2
│ └── folder3
│ └── file3
├── folder4
│ ├── file4a
│ ├── file4b
│ └── file4c
└── folder5
└── folder6
├── file6
└── folder7
└── folder8
└── folder9
├── dir9
└── file9
$ ./script
$ tree folder1
folder1
├── file1
├── folder3
│ └── file3
├── folder4
│ ├── file4a
│ ├── file4b
│ └── file4c
└── folder6
├── file6
└── folder9
├── dir9
└── file9