Linux:將不同目錄中具有相同名稱的檔案移到一個目錄中,同時重新命名它們

Linux:將不同目錄中具有相同名稱的檔案移到一個目錄中,同時重新命名它們

我將舊 CD 批量翻錄為 Track1.mp3。問題是每個 CD 目錄都有 Track1.mp3,所以當我將它們移到 /Music 時,它們會覆蓋!

是否可能有 bash 腳本或 mv 指令移動.mp3 從具有相同檔案名稱的多個子目錄複製到單一目錄中,同時重新命名它們(如果名稱已存在於 LINUX 下)?

答案1

您很可能需要“友好”的重命名。假設你有一個像

Artist1-+
        +-AlbumA-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumB-+
                 +-Track1.mp3
                 +-Track2.mp3
Artist2-+
        +-AlbumX-+
        |        +-Track1.mp3
        |        +-Track2.mp3
        +-AlbumY-+
        |        +-Track1.mp3
        |        +-Track2.mp3

您現在希望單一目錄包含類似的內容

Artist1-AlbumA-Track1.mp3
Artist1-AlbumA-Track2.mp3
...
Artist2-AlbumY-Track1.mp3
Artist2-AlbumY-Track2.mp3

bash這可以透過一個簡單的循環來實現

for M in */*/*.mp3; do
  TRACK=$(basename "$M")
  ALBUM=$(basename $(dirname "$M"))
  ARTIST=$(basename $(dirname $(dirname "$M")))
  mv "$M" "$TARGET_DIR/$ARTIST-$ALBUM-$TRACK"
done

答案2

cp和命令mv透過選項支援此功能--backup

來自手動的:

   --backup[=CONTROL]
          make a backup of each existing destination file

   -b     like --backup but does not accept an argument

[...]

備份後綴為“~”,除非使用 --suffix 或 SIMPLE_BACKUP_SUFFIX 設定。版本控制方法可以透過 --backup 選項或透過 VERSION_CONTROL 環境變數來選擇。以下是這些值:

   none, off
          never make backups (even if --backup is given)

   numbered, t
          make numbered backups

   existing, nil
          numbered if numbered backups exist, simple otherwise

   simple, never
          always make simple backups

所以例如mv --backup=t <source_file> <dest_file>應該有效。

答案3

根據 Linux 社群和 commandlinefu.com 的說法,迄今為止的任何版本都無法實現這項便利功能。

目前沒有命令也沒有確定的方法可以透過命令列將檔案從具有相同名稱的多個目錄和子目錄移動到單一目錄中,而不覆蓋它們。

資料來源:commandlinefu.com、askubuntu.com、linuxquestions.org、superuser.com

答案4

我假設你有這樣的資料夾結構:

$ tree .
.
├── artist1
│   ├── albuma
│   │   └── Track1.mp3
│   └── albumb
│       └── Track1.mp3
└── artist two
    ├── album one
    │   └── Track1.mp3
    └── album two
        └── Track1.mp3

首先,cd前往 MP3 收藏的父資料夾( 的父資料夾artist1)。

現在,如果您執行以下find命令,您將看到以下輸出:

$ find . -name '*.mp3' -exec bash -c 'echo mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' bash {} \;
mv -v ./artist two/album one/Track1.mp3 /tmp/music/artist-two-album-one-Track1.mp3
mv -v ./artist two/album two/Track1.mp3 /tmp/music/artist-two-album-two-Track1.mp3
mv -v ./artist1/albuma/Track1.mp3 /tmp/music/artist1-albuma-Track1.mp3
mv -v ./artist1/albumb/Track1.mp3 /tmp/music/artist1-albumb-Track1.mp3
  • find收集 MP3 檔案的所有路徑,例如./artist two/album one/Track1.mp3並將它們傳遞給bashvia-exec
  • $(echo "$1" | sed "s/\.\///" | tr " /" "-")用於修改輸出檔名。sed刪除第一個./並將tr所有空格字元 和 轉換/-

必須find.起始目錄運行,否則(相對)輸出路徑將無法正確修改。更改/tmp/music/為您的音樂庫的路徑。

如果輸出看起來不錯,請刪除第一個echo並再次執行該命令。

輸出:

$ find . -name '*.mp3' -exec bash -c 'mv -v "$1" /tmp/music/$(echo "$1" | sed "s/\.\///" | tr " /" "-")' babbsh {} \;
'./artist two/album one/Track1.mp3' -> '/tmp/music/artist-two-album-one-Track1.mp3'
'./artist two/album two/Track1.mp3' -> '/tmp/music/artist-two-album-two-Track1.mp3'
'./artist1/albuma/Track1.mp3' -> '/tmp/music/artist1-albuma-Track1.mp3'
'./artist1/albumb/Track1.mp3' -> '/tmp/music/artist1-albumb-Track1.mp3'

相關內容