目标是将文件移出最低级文件夹,备份一个目录。
这项工作做得很好,但同时也将文件移动到了更高的文件夹层次结构中。
find . -name '*.jpg' -type f -execdir mv '{}' ../ \;
因此,如果这些 jpg 位于名为“照片”的文件夹中,我想将它们上移一级,例如)
../
我尝试更改“*.jpg”参数以包含文件夹,并尝试使用文件夹而不是文件后的点。还尝试了 -maxdepth 和 -mindepth,但它们没有效果。
编辑:这是针对多个文件夹,即它需要遍历整个驱动器。
答案1
将文件从最低子目录向上移动一级
下面的脚本搜索目录最低的子目录(=没有子目录)递归并将文件夹中找到的所有文件上移一级,正如字面要求的那样目标是将文件移出最低级文件夹,备份一个目录:
#!/usr/bin/env python2
import shutil
import os
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for dr in dirs:
dr = root+"/"+dr
# find folders without subfolders (= lowest level)
if len(next(os.walk(dr))[1]) == 0:
# direct superior directory
up = dr[:dr.rfind("/")]
# move files from lowest level one level up
for f in os.listdir(dr):
shutil.move(dr+"/"+f, up+"/"+f)
使用方法:
- 将脚本复制到一个空文件中,另存为
reorganize.py
通过命令运行:
python /path/to/reorganize.py <directory_to_reorganize>
如果您的目录(要重新组织)的名称包含空格,请使用引号:
python /path/to/reorganize.py '<directory_to_reorganize>'
编辑
正如评论中提到的那样,只需稍加改动,该脚本就可以用来仅移动文件夹中的文件姓名上一级。最有效的方法是在
for dr in dirs:
那么脚本将是:
#!/usr/bin/env python3
import shutil
import os
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for dr in dirs:
if dr == "<folder_name>":
dr = root+"/"+dr
# direct superior directory
up = dr[:dr.rfind("/")]
# move files from lowest level one level up
for f in os.listdir(dr):
shutil.move(dr+"/"+f, up+"/"+f)
答案2
如果文件仅位于名为 的目录下(可以有多个名为 的目录),则以下操作会将所有.jpg
文件移动到其各自的父目录中:.jpg
photos
photos
find . -type f -path '*/photos/*' -not -path '*/photos/*/*' -name '*.jpg' \
-execdir mv -i {} .. \;
-path '*/photos/*'
将确保路径包含photos
但文件只能位于目录下photos
(-not -path '*/photos/*/*'
)。
还要注意,如果不要旅行的目录(不是photos
)是固定的、数量较少或有特定的模式,那么您可能也会感兴趣-prune
。
答案3
如果所有目标文件都在名为的目录中photos
,您可以执行以下操作:
find . -type d -name photos -exec bash -c 'cd {} && mv *jpg ../' \;
它将查找目录名称photos
,然后启动一个 bash shell,cd
进入每个目录并将所有.jpg
文件移动到父目录。
答案4
将在每个目录分支中找到最低级别,并使用它作为查找的基础,然后将“*.jpg”向上移动一级。
#!/bin/bash
treedir="."
mapfile -d '' < <(find "$treedir" -depth -type d -print0)
L=""
A=()
for D in "${MAPFILE[@]}"; do
[[ $L != $D/* ]] && A+=("$D"); L="$D"
done
for basedir in "${A[@]}"; do
find "$basedir" -name '*.jpg' -type f -execdir mv -i -t .. '{}' \;
done