디렉터리 계층 구조를 평면화하고 새 디렉터리 이름에 디렉터리 이름을 보존합니다.

디렉터리 계층 구조를 평면화하고 새 디렉터리 이름에 디렉터리 이름을 보존합니다.

저는 기본적으로 여기서 시작하고 싶습니다:

.
├── Alan Walker
│   ├── Different World
│   │   ├── 01 Intro.mp3
│   │   ├── 02 Lost Control.mp3
│   │   └── cover.jpg
│   └── Same World
│       ├── 01 Intro.mp3
│       └── 02 Found Control.mp3
├── Aurora
│   └── Infections Of A Different Kind Step 1
│       ├── 01 Queendom.lrc
│       ├── 02 Forgotten Love.lrc
│       └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses
    └── Use Your Illusion I
        ├── 01 Right Next Door To Hell.lrc
        ├── 01 Right Next Door To Hell.mp3
        ├── 02 Dust N' Bones.lrc
        └── 02 Dust N' Bones.mp3

이와 관련하여:

.
├── Alan Walker - Different World
│   ├── 01 Intro.mp3
│   ├── 02 Lost Control.mp3
│   └── cover.jpg
├── Alan Walker - Same World
│   ├── 01 Intro.mp3
│   └── 02 Found Control.mp3
├── Aurora - Infections Of A Different Kind Step 1
│   ├── 01 Queendom.lrc
│   ├── 02 Forgotten Love.lrc
│   └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses - Use Your Illusion I
    ├── 01 Right Next Door To Hell.lrc
    ├── 01 Right Next Door To Hell.mp3
    ├── 02 Dust N' Bones.lrc
    └── 02 Dust N' Bones.mp3

내가 찾은 기존 솔루션에는 디렉터리 자체의 이름을 바꾸는 것이 포함되어 있지 않습니다. zmv로 이것을 할 수 있다면 좋을텐데 어떻게 해야할지 모르겠습니다.

답변1

어쩌면 이런 게 있지 않을까요?

#!/bin/sh

for topdir in */; do
    topdir_name=$( basename "$topdir" )

    for subdir in "$topdir"/*/; do
        subdir_name=$( basename "$subdir" )

        newdir="$topdir_name - $subdir_name"
        if mkdir "$newdir"; then
            mv "$subdir"/* "$newdir"
            rmdir "$subdir"
        fi
    done

    rmdir "$topdir"
done

이는 현재 디렉토리의 모든 최상위 디렉토리(밴드 이름)를 반복합니다. 이러한 각 디렉터리에 대해 해당 하위 디렉터리(앨범 이름)를 반복합니다. 밴드 이름과 앨범 이름의 각 쌍에 대해 새 디렉토리가 생성되고 하위 디렉토리의 파일이 해당 디렉토리로 이동됩니다. 앨범 하위 디렉터리는 원래 밴드 최상위 디렉터리와 마찬가지로 처리 후 삭제됩니다.

rmdir디렉터리에 숨겨진 파일 이름이 포함되어 있거나 새 디렉터리가 생성되지 않으면 호출이 실패합니다.

완전히 테스트되지 않은 코드입니다. 파일의 백업 사본에서 실행하십시오.

답변2

지쉬

테스트되지 않음:

zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)

두 번째 줄은 이전에 파일이 없었던 디렉토리를 포함하여 모든 빈 디렉토리를 삭제합니다. 이 문제는 mv콘텐츠가 이동되는 디렉터리를 기록하는 사용자 지정 래퍼를 사용하여 해결할 수 있습니다 .

이는 현재 디렉토리의 디렉토리에 대한 기호 링크를 순회합니다.

Linux 이름 바꾸기 유틸리티

검증되지 않은.

rename / ' - ' */*/
rmdir -- */ 2>/dev/null

이는 현재 디렉터리와 그 하위 디렉터리의 디렉터리로 심볼릭 링크를 통과합니다. 두 번째 줄은 이전에 파일이 없었던 디렉토리를 포함하여 모든 빈 디렉토리를 삭제합니다.

Perl 이름 바꾸기 스크립트

검증되지 않은.

prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null

이는 현재 디렉터리와 그 하위 디렉터리의 디렉터리로 심볼릭 링크를 통과합니다. 두 번째 줄은 이전에 파일이 없었던 디렉토리를 포함하여 모든 빈 디렉토리를 삭제합니다.

이는 이름이 변경된 디렉터리만 삭제하는 보다 정교한 방법입니다. 다시 말하지만, 테스트되지 않았습니다.

prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/

답변3

전략적으로 파일을 이동하는 대신 현재 구조를 유지하고 필요한 새 구조에 대한 링크를 만드는 것을 고려해 보셨나요?

전술적으로 이 작업을 수행하는 패턴은 다음과 같습니다.

find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c \
  'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}
  • find현재 작업 디렉터리(밴드가 포함된 디렉터리여야 함)에서 정확히 두 수준 깊이의 모든 디렉터리를 찾습니다. 따라서 두 수준 깊이는 밴드 이름 아래의 앨범 이름입니다. 1
  • xargs앨범이 포함된 각 경로를 사용하고 인라인 bash 스크립트를 호출합니다.
  • bash -c '...'앨범 경로를 첫 번째 인수로 사용하여 경로를 밴드( $b)와 앨범( $a)의 두 부분으로 나눕니다. 마지막으로 스크립트는 이름을 원하는 형식으로 재조립하고 새 디렉터리 이름을 원래 디렉터리에 연결합니다.

이 경우 링크는 시작한 디렉터리와 동일한 디렉터리에 생성되며, 밴드 이름도 해당 디렉터리에 생성됩니다.

ln귀하의 의도에 맞게 위의 전략을 조정할 수 있고 조정해야 합니다 . mv다시 정렬하거나 ln미디어에 편리한 "보기"를 만들려면 올바른 경로를 사용하십시오. Bash 스크립트의 중요한 부분은 다음과 같습니다.

  • $b밴드 이름. 항상 인용하세요: "$b".
  • $a앨범 이름입니다. 항상 인용하세요: "$a".
  • $1앨범 디렉터리의 물리적 경로입니다. 항상 인용하세요: "$1".

1m{ax,in}depth 나는 GNU와 일부 BSD가 이를 지원한다고 생각 find하지만 POSIX는 지원하지 않습니다. 이 경우 */*쉘 체조 또는 이와 유사한 것에 의존합니다.

관련 정보