2012-04-16 4 views
0

Моя проблема в том, что у меня слишком много файлов в одном каталоге. Я не могу «ls», каталог слишком большой. Мне нужно переместить все файлы в лучшую структуру каталогов.Как переместить много файлов в несколько разных каталогов (на Linux)

Я использую последние 3 цифры из ID как папки в обратном порядке.

Например, ID 2018972 должен отправиться в /2/7/9/img_2018972.jpg.

Я создал каталоги, но теперь мне нужна помощь с скриптом bash. Я знаю идентификаторы, есть диапазон 1,300,000 - 2,000,000. Но я не могу обрабатывать регулярные выражения.

Я wan't, чтобы переместить все файлы, как это:

/images/folder/img_2018972.jpg -> /images/2/7/9/img_2018972.jpg 

Я буду признателен за любую помощь по этому вопросу. Благодаря!

+0

вы можете эмулировать 'ls', используя что-то вроде; 'для f в *; do printf - "% s \ t" "$ f"; done' и 'ls -1' с' for f in *; do printf - "% s \ n" "$ f"; сделано'. 'ls' терпит неудачу из-за' ARG_MAX', ограничение максимальных аргументов. – c00kiemon5ter

+0

Спасибо за повторы, я забыл упомянуть, что в папке у меня больше файлов jpg с одинаковой структурой имен файлов, но с «_220, _380» в конце .. например: img_1234567_220.jpg. – Alex

+0

Ты имеешь в виду, что ты не хочешь соответствовать этим? или ответ хорошо? – c00kiemon5ter

ответ

1

EDIT: после explainations в комментариях следующие предположения существует:

  • имена файлов в виде img_<id>.jpg или img_<id>_<size>.jpg
  • новый реж является обратный порядок из трех последних цифр идентификатор

с помощью Bash:

for file in /images/folder/*.jpg; do 
    fname="${file%.*}"  # remove extension and _<size> 
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}" 

    last0="${fname: -1:1}" # last letter/digit 
    last1="${fname: -2:1}" # last but one letter/digit 
    last2="${fname: -3:1}" # last but two letter/digit 

    newdir="/images/$last0/$last1/$last2" 
    # optionally check if the new dir exists, if not create it 
    [[ -d "$newdir" ]] || mkdir -p "$newdir" 

    mv "$file" "$newdir" 
done 

если * не может справиться с этим (хотя я думаю, что * в цикле не имеет ограничений),
использование find как это было предложено @ Михал Kosmulski в комментариях

while read -r; do 
    fname="${REPLY%.*}"  # remove extension and _<size> 
    [[ "$fname" =~ img_[0-9]+_[0-9]+$ ]] && fname="${fname%_*}" 

    last0="${fname: -1:1}" # last letter/digit 
    last1="${fname: -2:1}" # last but one letter/digit 
    last2="${fname: -3:1}" # last but two letter/digit 

    newdir="/images/$last0/$last1/$last2" 
    # optionally check if the new dir exists, if not create it 
    [[ -d "$newdir" ]] || mkdir -p "$newdir" 

    mv "$REPLY" "$newdir" 
done < <(find /images/folder/ -maxdepth 1 -type f -name "*.jpg") 
+0

Расширение оболочки '/ images/folder/*. Jpg', вероятно, не будет работать из-за огромного количества файлов, но вы можете заменить for-loop на' find/images/folder -maxdepth 1-type f -name '* .jpg' | при чтении; do ; done' –

+0

добавил эту опцию, хотя я думаю, что '*' не имеет ограничений при использовании в цикле. существуют ограничения при использовании в качестве аргумента функции/script; 'ARG_MAX'. – c00kiemon5ter

+0

Спасибо за большую помощь. Я использовал вторую версию скрипта (где мы используем find, как это предложил @ Michał Kosmulski в комментариях). Он отлично работает, даже в папке так много файлов, что я даже не могу подсчитать ... Я полагаю, что более 2 - 3 миллионов файлов. Посмотрим, когда это будет завершено. Спасибо всем за вашу помощь! – Alex

0
find /images/folder -type f -maxdepth 1 | while read file 
do 
filelen=${#file} 
((rootn=$filelen-5)) 
((midn=$filelen-6)) 
((topn=$filelen-7)) 
root=${file:$rootn:1} 
mid=${file:$midn:1} 
top=${file:$topn:1} 
mkdir -p /images/${root}/${mid}/${top} 
mv $file /images/${root}/${mid}/${top} 
done 
+0

Я думаю, что это слишком много работы, вычисляя смещения. также в UNIX и UNIX, таких как ОС, имена файлов могут содержать что угодно. Вам лучше добавить некоторые цитаты и посмотреть '-r' на' read'. Попробуйте 'help read' в вашей оболочке;) – c00kiemon5ter

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