![从目录中读取文件并按扩展名组织到相应的文件夹中](https://linux22.com/image/87607/%E4%BB%8E%E7%9B%AE%E5%BD%95%E4%B8%AD%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6%E5%B9%B6%E6%8C%89%E6%89%A9%E5%B1%95%E5%90%8D%E7%BB%84%E7%BB%87%E5%88%B0%E7%9B%B8%E5%BA%94%E7%9A%84%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B8%AD.png)
我正在尝试创建一个 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/
请注意,我假设您要将所有文件直接放在目标目录下。如果您想重现目录层次结构,那就是另一回事了,并且不同的工具将是合适的。