Linux Bash脚本,用于根据扩展名将文件排序到子文件夹中

Linux Bash脚本,用于根据扩展名将文件排序到子文件夹中,linux,bash,shell,Linux,Bash,Shell,我的结构如下: FolderA Sub1 Sub2 filexx.csv filexx.doc FolderB Sub1 Sub2 fileyy.csv fileyy.doc FolderA Sub1 filexx.csv Sub2 filexx.doc FolderB Sub1 fileyy.csv Sub2 fileyy.doc

我的结构如下:

FolderA
    Sub1
    Sub2
    filexx.csv
    filexx.doc
FolderB
    Sub1
    Sub2
    fileyy.csv
    fileyy.doc
FolderA
    Sub1
        filexx.csv
    Sub2
        filexx.doc

FolderB
    Sub1
        fileyy.csv
    Sub2
        fileyy.doc
我想编写一个脚本,将.csv文件移动到每个父目录文件夹a、文件夹B等的文件夹sub1中,并提供以下结构:

FolderA
    Sub1
    Sub2
    filexx.csv
    filexx.doc
FolderB
    Sub1
    Sub2
    fileyy.csv
    fileyy.doc
FolderA
    Sub1
        filexx.csv
    Sub2
        filexx.doc

FolderB
    Sub1
        fileyy.csv
    Sub2
        fileyy.doc
这是我现在所拥有的,但是我得到了错误mv:cannot stat*.csv:No这样的文件或目录

我是bash脚本新手,所以如果我犯了一个非常明显的错误,请原谅我。我知道我也可以在Python中实现这一点,但它会更长,这就是为什么我想要使用linux命令的解决方案

find . -name "*.csv" -type f -execdir mv '{}' Sub1/ \;
使用find,搜索扩展名为.csv的所有文件,然后当我们找到它们时,从包含文件的目录中执行move命令,将文件移动到目录Sub1

find . -name "*.doc" -type f -execdir mv '{}' Sub2/ \;

对于扩展名为.doc的文件,请遵循相同的原则,但这次,请将文件移动到Sub2。

如果从当前目录的角度来看,要移动的csv文件位于顶级目录中,但不在其子目录中,则只需执行以下操作:

#!/bin/bash

for dir in */; do
    mv -v "$dir"*.csv "${dir}Sub1/"
    mv -v "$dir"*.doc "${dir}Sub2/"
done
如果希望以类似方式移动所有子目录中的文件,则:

shopt -s globstar
for file in **/*.csv; do
    mv -v "$file" "${file%/*}/Sub1/"
done
for file in **/*.doc; do
    mv -v "$file" "${file%/*}/Sub2/"
done

请注意,目录Sub1和Sub2与csv和doc文件所在的目录相对。

我相信您会遇到此错误,因为没有文件与通配符匹配。当它发生时,for循环将给$f通配符本身的值。您基本上是在尝试移动不存在的文件*.csv

为了防止这种行为,可以在脚本顶部添加shopt-s nullglob。使用此选项时,如果找不到文件,脚本将不会进入循环

我的建议是,在使用这样的通配符时,确保从正确的位置运行脚本。但是,您编写*/*/*.csv的目的可能是递归地匹配所有csv文件。如果这是你想要做的,这不是正确的方法

要使用native bash递归匹配所有csv/doc/etc文件,可以将shopt-s globstar添加到脚本顶部,并使用**/*.csv作为通配符

!/bin/bash shopt-s globstar nullglob 对于**/*.csv中的f;做 mv$f Destination/注意,$f被用于处理文件名中的空白的 完成 您还可以使用该实用程序来实现这一点。但是,如果您计划对文件进行更多的处理,而不仅仅是移动它们,那么for循环可能会更干净,因为您不必在同一个命令中内联所有内容


旁注:正如您所说的,Linux命令实际上不是Linux命令,它们是GNU实用程序的一部分

是的,我正在尝试递归地执行它!非常感谢您的旁注。@user42 note但是这不是递归的!正如Nejat所说,只有当您要移动的csv文件位于顶级目录中时,这才有效