如何按文件扩展名将文件目录拆分为命名子目录?

如何按文件扩展名将文件目录拆分为命名子目录?

我有一个包含此类文件的目录

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

使用zshfrom (并在脚本中bash使用缩写形式,并将变量名称压缩为):forzsh -cnamen

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

相关内容