从目录中读取文件并按扩展名组织到相应的文件夹中

从目录中读取文件并按扩展名组织到相应的文件夹中

我正在尝试创建一个 bash 函数脚本,该脚本允许我创建多个具有以下名称的目录。我还尝试按扩展名将文件组织到相应的文件夹中(即 .jpg 到图片中,.doc 到文档中,.gif 到媒体中,等等)。第一部分很好,但目录创建后的后半部分让我感到困惑。

    #!/bin/bash
    echo "Creating directory categories"

    function make_folder 
    {
        cd -; cd content; sudo mkdir ./$1
    }

    make_folder "documents"
    make_folder "other"
    make_folder "pictures"
    make_folder "media"

    echo "Directories have been made"; cd -
    exit

    ext="${filename##*.}" #set var ext to extension of files

    find ./random -name | #find and list all files in random folder
                          #pipe results of find into if statement

    if ext == ["jpg"; "jpeg"; "png"] #move ".jpg", etc to new destination
         then
           mv /path/to/source /path/to/destination

    elif ext == [".gif"; ".mov"] #move ".gif", etc to new destination 
         then
           mv /path/to/source /path/to/destination
    else                         #move other files into to new destination
           mv /path/to/source /path/to/destination
    fi

答案1

从我的头脑中,我最终会使用“case”语句。

IE

case "$FILE" in
    *.jpg|*.jpeg)
        mv "$FILE" to where you want it
        ;;
    *.gif|*.mov)
        mv "$FILE" to where you want it
        ;;
    *)
        echo "Unmanaged file type: $FILE, skipping"
        ;;
 esac

...但是您需要将其包装在循环容器中,并且您确定要使用 find,那么它可能适合;

 find <your stuff> | 
     while read FILE
     do
         ...case statement goes here
     done

只是我的 0.02 美元

干杯! / 丹尼尔

答案2

您的make_folder功能不必要地复杂:所有这些当前目录更改只会让您的生活变得更加复杂。最重要的是,您不需要sudo:为什么要以 root 身份创建目录?就打电话吧mkdir

mkdir documents other pictures media

如果您希望脚本在目录已经存在的情况下也能工作,请使用mkdir -p

mkdir -p documents other pictures media

如果您想使用find,请不要让它打印名称然后解析它们。让find执行你想要的代码-exec。除了调用简单的程序之外,还可以调用 shell。对于<code>sh -c '<em>shell code</em>',shell 代码之后的下一个参数sh在 shell 代码中可用为$0始终在变量替换两边加上双引号。在 shell 片段中,通过扩展进行区分的自然方法是使用案件根据文件名构造。我用参数扩展构造${0##*/}以获取文件的基本名称(删除最后一个斜杠之前的所有内容)。该测试[ -e "$destination_file" ]测试目标文件是否已存在,以避免覆盖从不同目录移动的同名文件。

find random -exec sh -c '
  case "$0" in
    *.gif|*.png|*.jpg) destination_directory=pictures;;
    *) destination_directory=other;;
  esac
  destination_file="$destination_directory/${0##*/}"
  if [ -e "$destination_file" ]; then mv "$0" "$destination_file"; fi
' {} \;

另一种方法是按目的地复制文件,如果您有大量文件,这种方法可能会慢一些,但编写起来要简单得多。在 Linux 上,感谢 GNU 实用程序,它就像这样简单

find random \( -name '*.gif' -o -name '*.png' -o -name '*.jpg' \) -exec mv -n -t pictures {} +

对于其他目标目录也是如此。使用+而不是;在末尾通过批量find -exec调用来加快速度。mv

但事实上,对于您正在做的事情,在 bash 或 zsh 中,您不需要find.使用**通配符用于递归目录遍历。

shopt -s globstar # necessary in bash to enable **
mv -n random/**/*.gif random/**/*.png random/**/*.jpg pictures/

请注意,我假设您要将所有文件直接放在目标目录下。如果您想重现目录层次结构,那就是另一回事了,并且不同的工具将是合适的。

相关内容