如何创建一个 bash 函数来创建多个命名目录,然后按扩展名组织它们包含的文件?

How do I make a bash function to create multiple named directories and then organize their included files by extension?

我正在尝试创建一个 bash 函数脚本,它允许我使用以下名称创建多个目录。每次我 运行 它都很好地回显,但在两者之间它说(mkdir:./:文件存在),但是那里已经没有文件了。我究竟做错了什么?我应该补充一点,为了清楚起见,该脚本是我根目录中名为 bin 的另一个文件夹。

   #!/bin/bash

    echo "Creating directory categories"

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

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

    echo "Directories have been made"; cd -
    exit

更新:我也在尝试通过扩展名将文件组织到相应的文件夹中(即 .jpg 到图片,.doc 到文档,.gif 到媒体等)。

   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

在 bash 中,函数的参数是通过变量 $1、$2 等访问的

如问题中所写,变量 $folder 尚未设置,因此 mkdir ./$folder 命令将扩展为存在的 mkdir ./(因此出现错误消息)

以下小调整会有所帮助:


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

这是您的代码的高效、惯用的重新表述:

#!/bin/bash

# Note how I'm using *single* quotes for all strings that should be
# treated as *literals* (strings that need no interpolation).
echo 'Creating directory categories'

make_folders()
{
    # Create subfolders, prefixed with `./content/`
    # "${@}" is the array of all arguments (parameters) and parameter 
    # expansion `/#/./content/` replaces (`/`) the beginning of each parameter
    # (`#`) with string './content/', which effectively prepends './content/` to
    # each argument.
    sudo mkdir -p "${@/#/./content/}"
}

# Change to the root folder here; e.g.:
# Without an argument, `cd` changes to the current user's home folder.
# (This won't usually fail, but it's always a good idea to check.)
cd || { echo 'Error.' >&2; exit 1; }
# Alternatively, do nothing to start with the *current* dir,
# or use `cd -- "${BASH_SOURCE%/*}"` to change to the folder in which 
# the script resides.

make_folders 'documents' 'other' 'pictures' 'media' || { echo 'Error.' >&2; exit 1; }

echo 'Directories have been made'

至于你尝试过的:

  • cd - 更改为 previous 目录,无论它是什么,都存储在 $OLDPWD 中;在脚本中,$OLDPWD 它最初是 未设置 ,导致 cd 命令失败并显示错误消息 cd: OLDPWD not set

    • 最好避免改变当前目录。完全一样,或者在脚本的开头做一次,或者将更改范围限定为 subshell.
    • Gordon Davisson在评论中指出,如果确实使用了cd,应该经常检查它的退出码,看是否成功,以确保后续的命令真正操作在打算 files/directories.
  • ./$folder 引用了您从未设置过的变量 $folder;如前所述,传递给函数的参数可以作为 </code>、<code>、... 或统称为 array $@.

    • 此外,作为一般规则,您应该始终 双引号 变量引用(除非您特别希望 shell 按空格和主题将它们拆分为单词他们通配(路径名扩展));在您的情况下,这意味着 "./$folder".
  • 由于用户自定义函数和mkdir都支持传递多个参数,因此相应地定义函数并传递一次性创建所有文件夹