根据特定条件将文件从一个文件夹移动到另一个文件夹

根据特定条件将文件从一个文件夹移动到另一个文件夹

我有数十万个照片文件夹。无论出于什么原因,在导出时,它们都创建了以下几种情况:

2019/01/01
2019/01/01 #2

如何编写一个 Linux 命令(最好可以在 Mac 上运行)来自动移动文件

from 
2019/01/01 #2 
to 
2019/01/01

任何帮助都将不胜感激。这需要适用于任何日期,并合并内容。我苦苦挣扎的地方是,我无法理解如何在没有 # 的情况下将目录获取为原始格式

for dir in *#2/*; do mv "$dir"/* "${dir}"; done

答案1

使用find-exec

find . -type d -name "* #*" -exec bash -O nullglob -c '
  for dir; do
    otherdir=${dir/ #*}
    if [ -d "$otherdir" ]; then
      for file in "$dir"/*; do
        mv -vi "$file" "$otherdir"
      done
      rmdir "$dir" && echo "deleted directory $dir"
    else
      mv -v "$dir" "$otherdir"
    fi
  done
' bash {} +

如果后一个目录存在,则此操作会将所有文件从 移动2019/01/01 #22019/01/01(如果不存在,则#重命名带有 的文件夹)。如果 中有文件2019/01/01 #2已存在于另一个文件夹中,则它会请求移动文件的权限。
移动操作完成后,它会尝试删除(现在为空的)文件夹。所有移动/删除操作都处于详细模式。

nullglob与 for 循环结合启用可确保"$dir"/*如果目录已为空则不会返回任何文件。

答案2

尝试此操作之前请备份您的文件。这可能会造成破坏...

问题的一部分在于for,在遍历名称中带有空格的文件夹时使用。您最终会得到一个不一致的列表,因为空格和回车符都是字段分隔符。您需要设置IFS为仅回车符。(您可以使用find -exec直接处理文件系统条目,但变得混乱使用嵌套通配符时

这应该可以完成工作,但要注意移动的文件将覆盖目标文件夹中匹配的文件。从上面的根文件夹运行它。

# Set IFS to carriage return only.
IFS='
'
# Find all the matching folders and move the .jpg files out of them to the sibling folder.
for a in $(find . -type d -name *#*); do b=${a::-3}; mv $a/*.jpg $b/; rmdir $a; done

做了一些假设: - 您描述的结构是年/月/日子文件夹。(如果文件夹名称包含\它会变得更丑陋) - 您只有一些带后缀的文件夹#2- 您想要在将文件移出后删除 #2 文件夹。

这里关于如何在 Bash 中使用字符串做更多奇怪的事情……

相关内容