![如何按文件扩展名将文件目录拆分为命名子目录?](https://linux22.com/image/213095/%E5%A6%82%E4%BD%95%E6%8C%89%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D%E5%B0%86%E6%96%87%E4%BB%B6%E7%9B%AE%E5%BD%95%E6%8B%86%E5%88%86%E4%B8%BA%E5%91%BD%E5%90%8D%E5%AD%90%E7%9B%AE%E5%BD%95%EF%BC%9F.png)
我有一个包含此类文件的目录
2022-11-08-0001.gzip
2022-11-08-0002.gzip
2022-11-08-0003.txt
2022-11-08-0004.png
2022-11-08-0005.txt
2022-11-08-0006.txt
2022-11-08-0007.png
2022-11-08-0008.txt
2022-11-08-0009.txt
2022-11-08-0010.png
并想像这样将它们分成子目录
/gzip
2022-11-08-0001.gzip
2022-11-08-0002.gzip
/png
2022-11-08-0004.png
2022-11-08-0007.png
2022-11-08-0010.png
/txt
2022-11-08-0003.txt
2022-11-08-0005.txt
2022-11-08-0006.txt
2022-11-08-0008.txt
2022-11-08-0009.txt
我发现这个简短而甜蜜的解决方案,但我无法根据我的需要自定义它,因为文件扩展名的长度各不相同。不过,文件的基本名称长度相同。
答案1
使用zsh
(并假设该模式与2022-*.*
所有相关文件匹配,即名称以字符串开头2022-
且至少包含一个点的文件):
for name in 2022-*.*; do
mkdir -p $name:e && mv $name $name:e
done
在 中zsh
,$variable:e
将与 相同$variable
,但删除最后一个点之前的所有内容(保留“扩展名”)。
测试:
$ tree
.
|-- 2022-11-08-0001.gzip
|-- 2022-11-08-0002.gzip
|-- 2022-11-08-0003.txt
|-- 2022-11-08-0004.png
|-- 2022-11-08-0005.txt
|-- 2022-11-08-0006.txt
|-- 2022-11-08-0007.png
|-- 2022-11-08-0008.txt
|-- 2022-11-08-0009.txt
`-- 2022-11-08-0010.png
0 directories, 10 files
$ for name in 2022-*.*; do mkdir -p $name:e && mv $name $name:e; done
$ tree
.
|-- gzip
| |-- 2022-11-08-0001.gzip
| `-- 2022-11-08-0002.gzip
|-- png
| |-- 2022-11-08-0004.png
| |-- 2022-11-08-0007.png
| `-- 2022-11-08-0010.png
`-- txt
|-- 2022-11-08-0003.txt
|-- 2022-11-08-0005.txt
|-- 2022-11-08-0006.txt
|-- 2022-11-08-0008.txt
`-- 2022-11-08-0009.txt
3 directories, 10 files
使用zsh
from (并在脚本中bash
使用缩写形式,并将变量名称压缩为):for
zsh -c
name
n
zsh -c 'for n; mkdir -p $n:e && mv $n $n:e' zsh 2022-*.*
答案2
您只需遍历每个文件名,如果尚不存在,则创建匹配的目录,然后将文件移动到那里。就像是
#!/bin/bash
for filename in *; do
# if filename is not a regular file, skip
[ -f "${filename}" ] || continue
# ${}: variable expansion
# ${variable/pattern/replacement}: Pattern Replacement
# pattern begins with #, meaning it must start at beginning of name
# pattern is *., meaning "all up to the last dot"
# replacement is empty
suffix="${filename/#*./}"
# skip files with no extension
[ "${suffix}" = "${filename}" ] && continue
# make that directory. Or ignore the fact it's already made.
mkdir -p "${suffix}"
mv "${filename}" "${suffix}"
done