Пакетное переименование нескольких файлов с разным путем - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть каталог с файлами music/artist/{random_name}/{random_music}.ogg

В {random_name} много папок и различный музыкальный заголовок {random_music}.

Итак, я хотел переименовать *От 1008 * до music.ogg.В каждой папке {random_name} есть только один файл .ogg.

Я пытался с помощью скриптов Bash в течение нескольких часов, но не смог найти.

for f in ../music/artist/*/*.ogg
do
  echo mv  "$f" "${f/.*.ogg/music.ogg}"
done

Он только переименовывает файл в моем текущем каталоге, который попросит заменить /перезаписать.

Мои цели, я хотел переименовать все файлы {random_music}.ogg в music.ogg с их соответствующими каталогами, например,

music/artist/arai/blue.ogg в music/artist/arai/music.ogg

music/artist/sako/sky.ogg до music/artist/sako/music.ogg

Ответы [ 5 ]

0 голосов
/ 10 февраля 2019
find ../music/artist/ -type f -name "*.ogg" -exec bash -c 'mydir=`dirname {}`;mv {} $mydir/music.ogg' \;

Это однострочник, который должен работать.Он реализует опцию exec команды find, которая затем получает имя каталога и переименовывает исходный файл в music.ogg.

0 голосов
/ 10 февраля 2019

Надеюсь, это поможет вам:

Ранее:

[root@user]# tree music
music
└── artist
    ├── df
    │   └── mp.ogg
    ├── gh
    │   └── pl.ogg
    ├── jk
    │   └── gl.ogg
    ├── po
    │   └── ui.ogg
    ├── ty
    │   └── lk.ogg
    └── ui
        └── dh.ogg

7 directories, 6 files

Исходный код:

#!/bin/bash

for i in `ls -ld music/artist/* | awk '{print $9}'`
do
        mv $i/*ogg $i/music.ogg

done

После выполнения:

music
└── artist
    ├── df
    │   └── music.ogg
    ├── gh
    │   └── music.ogg
    ├── jk
    │   └── music.ogg
    ├── po
    │   └── music.ogg
    ├── ty
    │   └── music.ogg
    └── ui
        └── music.ogg

7 directories, 6 files

Как видите, все файлы были переименованы правильно.

0 голосов
/ 10 февраля 2019

Я обычно использую это:

for f in ../music/artist/*/*.ogg
do
    dest="${f/.*.ogg/music.ogg}"
    if [[ $f != "$dest" ]] # nothing to do if name doesn't change
    then 
        if [[ -a $dest ]]
        then
            printf 'WARNING: File already exists: %s\n' "$dest"
        else
            mv "$f" "$dest"
        fi
    fi
done
0 голосов
/ 10 февраля 2019

Вы можете изменить свой код следующим образом

for f in ../music/artist/*/*.ogg
do
  echo mv $f "$(dirname "$f")"/music.ogg
done

Здесь dirname извлечет имя каталога из вашей переменной, и вы можете добавить его с помощью music.ogg, чтобы получить желаемый результат.

Для примера пути, который вы указали

, если $f равно music/artist/arai/blue.ogg, то результат будет

mv music/artist/arai/blue.ogg music/artist/arai/music.ogg

0 голосов
/ 10 февраля 2019

Ваш шаблон заменен неверно.Поскольку все ваши пути начинаются с .., .*.ogg фактически соответствует всему пути , поэтому каждый файл превращается в music.ogg в вашем текущем каталоге.

Вы хотите ${f/\/*.ogg/music.ogg} вместо этого, или еще лучше, ${f%/*}/music.ogg.Это грубый эквивалент "$(dirname "$f")"/music.ogg.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...