파일 확장자별로 파일 디렉터리를 명명된 하위 디렉터리로 분할하는 방법은 무엇입니까?

파일 확장자별로 파일 디렉터리를 명명된 하위 디렉터리로 분할하는 방법은 무엇입니까?

그러한 파일을 포함하는 디렉토리가 있습니다

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

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

관련 정보