ファイル拡張子別にファイルディレクトリを名前付きサブディレクトリに分割する方法は?

ファイル拡張子別にファイルディレクトリを名前付きサブディレクトリに分割する方法は?

そのようなファイルを含むディレクトリがあります

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-少なくとも1つの点を含むファイルと一致すると仮定します)。

for name in 2022-*.*; do
    mkdir -p $name:e && mv $name $name:e
done

Inはと同じです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

from を使用しzsh、スクリプトで省略形式を使用し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

関連情報