2015-01-09 4 views
1

У меня есть каталог файлов. Я хочу объединить их в пакеты в n каталогов.Терминальный скрипт для группировки файлов в папки

Итак ...

"MyFolder" имеет файлы A, B, C, D, E, F, G, H, I, J

Я хочу, чтобы поместить их в, скажем, 3 партии ... дозируется, как это:

Folder 1 - A, B, C, D 

Folder 2 - E, F, G 

Folder 3 - H, I, J 

(а не так, как это ... что только так, как я могу работать это сам)

Folder 1 - A, D, G, J 

Folder 2 - B, E, H 

Folder 3 - C, F, I 

может кто-нибудь PLE асе посоветуйте мне, как это можно сделать?

Спасибо!

+0

Stackoverflow о помощи людям исправить их код. Отправьте свое, и мы сможем помочь. Удачи. – shellter

ответ

2

Это решение, которое использует список аргументов (единственный список, доступный для оболочки POSIX без использования дополнительных функций, например, bash). Обратите внимание на предостережение; достаточно большое количество файлов не будет вписываться в буфер аргументов. Также обратите внимание, что переполнение стека неправильно принимает $# (длина списка аргументов) начинает комментарий, поэтому раскраска немного выключена.

#!/bin/sh 

num_folders=3 # default to 3 directories 
if [ $# -gt 0 ]; then 
    num_folders=$1 
    shift 
fi 

# put all files into "argument" list 
# (CAVEAT: this won't work on a dir with a LOT of files) 
set - * 

batch=$(($#/$num_folders))  # files per folder 
remainder=$(($# % $num_folders)) # folders to get an "extra" file 

i=1 
while [ $i -le $num_folders ]; do 

    mkdir "Folder $i" 
    if [ $i -le $remainder ] 
    then j=0 
    else j=1 
    fi 

    while [ $j -le $batch ]; do 
    mv "$1" "Folder $i" 
    shift 
    j=$(($j + 1)) 
    done 

    i=$(($i + 1)) 
done 

Вот этот скрипт в действии (я использую # как подсказка, чтобы вызвать другой цвет для команд против выхода):

# touch A B C D E F G H I J 
# ls * 
A B C D E F G H I J 
# sh ../batch-n.sh 3 
# ls * 
Folder 1: 
A B C D 

Folder 2: 
E F G 

Folder 3: 
H I J 

Вот что происходит, когда п = 4

# touch A B C D E F G H I J 
# ls * 
A B C D E F G H I J 
# sh ../batch-n.sh 4 
# ls * 
Folder 1: 
A B C 

Folder 2: 
D E F 

Folder 3: 
G H 

Folder 4: 
I J 

Я поместил этот код в родительский каталог (поэтому я вызвал его как ../batch-n.sh), потому что он в противном случае сам загружал бы файл. Это будет прекрасно работать с файлами, в которых есть пробелы, если они все вписываются в одну команду (если ls * не может работать, этот сценарий тоже не может быть).

2

Установка:

mkdir /tmp/so 
cd /tmp/so 
touch {A..Z} # create 26 files 

Простейшая вещь, которая будет работать:

Live On Coliru

for a in Folder\ {1..8}; do mkdir -pv "$a"; read z y x w; mv -v "$z" "$y" "$x" "$w" "$a/"; done < <(ls ? | xargs -n4) 

Или, похорошела:

for a in Folder\ {1..8}; 
do mkdir -pv "$a" 
    read z y x w 
    mv -v "$z" "$y" "$x" "$w" "$a/" 
done < <(ls ? | xargs -n4) 

В качестве альтернативы, (немного лучше с именами, содержащими пробелы)

for a in Folder\ {1..8}; do mkdir -pv "$a"; read z && read y && read x && read w; mv -v "$z" "$y" "$x" "$w" "$a/"; done < <(ls ?) 
+0

Очень умная логика (браво на краткий обзор!), Но обратите внимание, что в этом коде есть несколько базизмов, которые не будут работать во всех оболочках POSIX. В частности, синтаксис dotdot ('{A..Z} и' {1..8} ') и подстановка команд (' <(command) ') не существуют в оболочках, которые проще, чем bash. Вики Ubuntu [хороший справочник по исправлению базизмов] (https://wiki.ubuntu.com/DashAsBinSh#I_am_a_developer._How_can_I_avoid_this_problem_in_future.3F), если вам интересно. –

+0

Я знаю об основах. Спасибо, что заметили это, если другие не знают! – sehe