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文件位于顶级目录中时,这才有效