2014-10-31 1 views
1

Я пытаюсь переименовать файлы в огромную папку изображений, которая содержит много подпапок и внутри них изображения.Рекурсивно переименовать коллекцию изображений с подпапками

Что-то вроде этого:

ImageCollection/ 
    January/ 
     Movies/ 
     123123.jpg 
     asd.jpg 
     Landscapes/ 
     qweqas.jpg 
    February/ 
     Movies/ 
     ABC.jpg 
     QWY.jpg 
    Landscapes/ 
     t.jpg 

И я хочу, чтобы запустить сценарий и переименовать их в порядке возрастания, но не держать их в соответствующей папке, например:

ImageCollection/ 
    January/ 
     Movies/ 
     0.jpg 
     1.jpg 
     Landscapes/ 
     2.jpg 
    February/ 
     Movies/ 
     3.jpg 
     4.jpg 
    Landscapes/ 
     5.jpg 

До сих пор у меня есть следующее:

#!/usr/bin/env bash 
x=0 
for i path/to/dir/*/*.jpg; do 
    new=$(printf path/to/dir/%d ${x}) 
    mv ${i} ${new} 
let x=x+1 
done 

Но моя проблема заключается в том, что мы не в состоянии сохранить файл es в их соответствующих подпапках, вместо этого все перемещается в корневую папку path/to/dir.

+0

Используйте команду find, получите список всех файлов (найдите свою папку для поиска | grep "\ .jpg $"), предоставит вам список. Используйте для цикла (со счетчиком, начинающимся с 0), и начните делать shenzi (mv $ {file} $ (dirname $ {file})/$ counter.jpg). Последняя строка для цикла будет ((counter ++)). –

ответ

1

Чистый раствор Bash (за исключением из mv, конечно):

#!/bin/bash 

shopt -s nullglob 

### Optional: if you also want the .JPG (uppercase) files 
# shopt -s nocaseglob 

i=1 
for file in ImageCollection/*/*.jpg; do 
    dirname=${file%/*} 
    newfile=$dirname/$i.jpg 
    echo mv "$file" "$newfile" && ((++i)) 
done 

Это не будет выполнять переименование, только показать, что это произойдет. Удалите echo, если вы довольны результатом, который вы видите.

Вы также можете использовать опцию -n для mv, чтобы не перезаписывать существующие файлы. (Я бы определенно использовал его в этом случае!). Если -n нет в наличии, вы можете использовать:

[[ ! -e $newfile ]] && mv "$file" "$newfile" && ((++i)) 

Это 100% безопасное в отношении имен файлов (или dirnames), содержащих пробелов или других забавных символов.

0
#!/bin/bash 

x=0 
for f in `find path_to_main_dir_or_top_folder | grep "\.jpg$"`; 
do 
    mv $f $(dirname $f)/$x.jpg && ((x++)) 
done 
echo shenzi 
  1. $ е будет содержать все файлы, полный путь для всех * .jpg файлов
  2. имя_директории команда даст вам путь заполнения (за исключением файла) для данного $ F файла.
  3. $ x.jpg сделает трюк. Значение $ x будет увеличиваться на итерацию в цикле.
+0

Если вы не хотите, чтобы команда «находить» выполняла рекурсию на самом глубоком уровне, используйте -maxdepth N, где N - это число (например: -maxdepth 3, чтобы найти * .jpg в текущей, вниз, вниз до папки 3-го уровня). –

+0

Это сработало очень хорошо, спасибо. – JohD

+0

@JohD Это работает ... пока вы не нажмете имя файла с пробелами или другими забавными символами. Удачи. –

Смежные вопросы