将所有文件移动到以文件名的一部分命名的子目录中

将所有文件移动到以文件名的一部分命名的子目录中

我有一个目录,其中包含很多文件,其名称由艺术家的姓名和专辑组成,例如: 在此输入图像描述

现在的任务是遍历每个文件,创建一个以艺术家姓名和专辑名称命名的目录,然后将文件移动到该目录中。

最终的结构应该是这样的: 在此输入图像描述

我该如何仅使用基本的 shell 命令来完成此操作?

答案1

这主要会做你想做的事,尽管你要求很多,所以如果有任何你感到困惑的部分,请告诉我,我会尽力解释它们:

#!/usr/bin/env bash

song_dir="$HOME/tmp/songs"
out_dir="$HOME/tmp/org_songs"

[[ ! -d "$out_dir" ]] && mkdir -p "$out_dir"

get_artist () {
    local a=($(tr '_' ' ' <<<"$1"))
    for i in "${a[@]}"; do
        if [[ $i =~ artiste.* ]]; then
            printf '%s\n' "${i#*=}"
            break
        fi
    done
}

get_album () {
    local a=($(tr '_' ' ' <<<"$1"))
    for i in "${a[@]}"; do
        if [[ $i =~ album.* ]]; then
            printf '%s\n' "${i#*=}"
            break
        fi
    done
}

get_song () {
    local a=($(tr '_' ' ' <<<"$1"))
    for i in "${a[@]}"; do
        if [[ $i =~ song.* ]]; then
            printf '%s\n' "${i#*=}"
            break
        fi
    done
}

for song in "${song_dir}/"*.mp3; do
    bname=$(basename "$song")
    artist=$(get_artist "$bname")
    album=$(get_album "$bname")
    sname=$(get_song "$bname")
    [[ ! -d "${out_dir}/${artist}/${album}" ]] && mkdir -p "${out_dir}/${artist}/${album}"
    cp "$song" "${out_dir}/${artist}/${album}/${sname}"
done

正在使用:

前:

$ tree
.
├── script.sh
└── songs
    ├── artiste=linkin-park_album=meteora_id=02_song=Don't-stay.mp3
    ├── artiste=linkin-park_album=meteora_id=02_song=Session.mp3
    ├── artiste=linkin-park_album=meteora_id=02_song=Somewhere-I-Belong.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Bleed-It-Out.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Given-Up.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Leave-out-All-The-Rest.mp3
    ├── id=01_artiste=eminem_album=recovery_song=cold-wind-blows.mp3
    ├── id=01_artiste=eminem_album=recovery_song=on-fire.mp3
    └── id=01_artiste=eminem_album=recovery_song=talking-2-myself-(feat-kobe).mp3

1 directory, 10 files

后:

$ tree
.
├── org_songs
│   ├── eminem
│   │   └── recovery
│   │       ├── cold-wind-blows.mp3
│   │       ├── on-fire.mp3
│   │       └── talking-2-myself-(feat-kobe).mp3
│   └── linkin-park
│       ├── meteora
│       │   ├── Don't-stay.mp3
│       │   ├── Session.mp3
│       │   └── Somewhere-I-Belong.mp3
│       └── minutes-of-midnight
│           ├── Bleed-It-Out.mp3
│           ├── Given-Up.mp3
│           └── Leave-out-All-The-Rest.mp3
├── script.sh
└── songs
    ├── artiste=linkin-park_album=meteora_id=02_song=Don't-stay.mp3
    ├── artiste=linkin-park_album=meteora_id=02_song=Session.mp3
    ├── artiste=linkin-park_album=meteora_id=02_song=Somewhere-I-Belong.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Bleed-It-Out.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Given-Up.mp3
    ├── artiste=linkin-park_album=minutes-of-midnight_id=04_song=Leave-out-All-The-Rest.mp3
    ├── id=01_artiste=eminem_album=recovery_song=cold-wind-blows.mp3
    ├── id=01_artiste=eminem_album=recovery_song=on-fire.mp3
    └── id=01_artiste=eminem_album=recovery_song=talking-2-myself-(feat-kobe).mp3

7 directories, 19 files

另请注意,我使用的cp是复制文件而不是mv移动它们。我建议先复制一份,然后只要一切正常就删除旧文件。否则,您可能会面临弄乱或丢失某些数据的风险。

相关内容