Meratakan hierarki direktori yang mempertahankan nama direktori dalam nama direktori baru

7

Saya pada dasarnya ingin beralih dari ini:

.
├── 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

untuk ini:

.
├── 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

Tidak ada solusi yang saya temukan termasuk mengganti nama direktori itu sendiri. Senang sekali bisa melakukan ini dengan zmv, tapi saya tidak tahu caranya.

aksh1618
sumber
2
Bukan solusi lengkap, jadi bukan jawaban: easytagbolehkan Anda melakukan ini, tetapi hanya untuk file audio - Saya tidak berpikir itu akan memindahkan sampul, dll.
rvs
2
Mungkinkah ada lebih dari satu album untuk artis tertentu dalam satu direktori artis? Apakah strukturnya selalu tiga tingkat dalam?
nohillside
1
@nohillside Ya, Mungkin ada lebih dari satu album untuk seorang artis. Dan ya, strukturnya selalu tiga tingkat.
aksh1618

Jawaban:

9

Zsh

Belum dicoba:

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

Baris kedua menghapus semua direktori kosong, bahkan yang tidak memiliki file sebelumnya. Dimungkinkan untuk menyiasatinya dengan mvpembungkus khusus yang mencatat dari direktori mana benda itu dipindahkan.

Perhatikan bahwa ini melintasi tautan simbolik ke direktori di direktori saat ini.

Linux mengganti nama utilitas

Belum dicoba.

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

Perhatikan bahwa ini melintasi tautan simbolik ke direktori di direktori saat ini dan di subdirektori. Baris kedua menghapus semua direktori kosong, bahkan yang tidak memiliki file sebelumnya.

Perl mengganti nama skrip

Belum dicoba.

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

Perhatikan bahwa ini melintasi tautan simbolik ke direktori di direktori saat ini dan di subdirektori. Baris kedua menghapus semua direktori kosong, bahkan yang tidak memiliki file sebelumnya.

Berikut adalah pendekatan yang lebih kompleks yang hanya menghilangkan direktori yang namanya diubah namanya. Sekali lagi, tidak diuji.

prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/
Gilles 'SANGAT berhenti menjadi jahat'
sumber
12

Mungkin sesuatu seperti ini?

#!/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

Ini melewati semua direktori tingkat atas di direktori saat ini (nama band). Untuk setiap direktori seperti itu, ia melewati subdirektori (nama album). Untuk setiap pasangan nama band dan nama album, direktori baru dibuat dan file dari subdirektori dipindahkan ke sana. Subdirektori album dihapus ketika mereka telah diproses, seperti juga direktori tingkat atas band asli.

The rmdirpanggilan akan gagal jika direktori setiap berisi nama file tersembunyi atau jika salah satu direktori baru gagal dibuat.

Ini benar-benar kode yang belum diuji. Jalankan pada salinan file Anda yang didukung.

Kusalananda
sumber
Maksud saya, ya, sesuatu seperti itu akan berhasil, tetapi saya agak mencari solusi satu atau dua jalur, untuk dijalankan dengan mudah dari terminal. Beberapa menemukan / sed / zmv magic :)
aksh1618
10
Masukkan ot ke dalam skrip, dan -boom- menjadi satu baris.
Hans-Martin Mosner
4

Secara strategis, daripada memindahkan file, sudahkah Anda mempertimbangkan untuk meninggalkan struktur saat ini di tempat dan membuat tautan untuk struktur baru yang Anda inginkan?

Secara taktik, sebuah pola yang akan melakukan pekerjaan berjalan seperti ini:

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"' {}
  • findmenempatkan semua direktori persis dua tingkat dalam dari direktori kerja saat ini, yang seharusnya menjadi direktori yang berisi band: dengan demikian dua tingkat adalah nama album di bawah nama band. 1
  • xargs menggunakan setiap jalur yang berisi album dan memanggil skrip bash sebaris.
  • bash -c '...'mengambil jalur album sebagai argumen pertama, memecah jalur itu menjadi dua bagian: band ( $b) dan album ( $a). Akhirnya, skrip menyusun kembali nama-nama ke dalam format yang diinginkan dan menautkan nama direktori baru ke direktori asli.

Perhatikan bahwa, dalam contoh ini, tautan akan dibuat di direktori yang sama dengan tempat Anda memulai, yang juga merupakan tempat nama band.

Anda dapat - dan harus - mengubah lnstrategi di atas agar sesuai dengan niat Anda. mvdengan jalur yang benar jika Anda ingin mengatur ulang secara fisik, atau lnjika Anda ingin membuat "tampilan" yang nyaman di media. Bagian penting di dalam skrip bash adalah:

  • $bnama band. Selalu mengutipnya: "$b".
  • $anama album. Selalu mengutipnya: "$a".
  • $1jalur fisik ke direktori album. Selalu mengutipnya: "$1".

1 Saya percaya m{ax,in}depthdidukung oleh GNU dan beberapa BSD find, tetapi tidak POSIX: dalam hal ini, bergantung pada */*atau senam shell serupa.

uskup
sumber
1
Saya suka jawaban ini ... Anda juga bisa membuat hardlink, lalu hapus struktur folder lama saat Anda puas
Thomas Zwaagstra
@ThomasZwaagstra Itu tidak berbeda dengan memindahkan file
Darkhogg
1
@Darkhogg Persis! OP sedang mencari 1-liner untuk memindahkan file. Menggunakan hardlink dengan solusi ini hampir akan mencapai itu, kecuali Anda akan memiliki tahap "pratinjau" menengah sebelum menghapus file asli
Thomas Zwaagstra