Если вам нужен каталог для каждого типа файлов, то вам нужно что-то вроде:
mkdir txt || { echo "Can't mkdir txt" ; exit 1 ; }
for file in *.txt ; do
mv -- "$file" txt/
done
Обратите внимание на обработку сбоев в mkdir
. В вашем коде, если уже существует файл с именем, содержащимся в переменной $dir
, ваша команда mkdir --"$dir"
будет молча отклонена, а затем ваша команда mv
перезапишет этот файл.
Чтобы обработать кучу файлов с произвольными именами - все файлы с трехсимвольными расширениями в текущем каталоге - и поместить их в каталоги по расширению файлов, вы можете использовать следующий код (не проверено):
for file in *.??? ; do
[ -f "$file" ] || continue
dir="$(echo "$file" | rev | cut -c-3 | rev)"
mkdir -p "$dir" || { echo "Couldn't mkdir -p $dir; exiting" ; exit 1 ; }
mv -- "$file" "$dir"
done
Объяснение:
Шаблон *. ???
будет соответствовать всем файлам и каталогам в текущем каталоге, имя которых заканчивается точкой (.
), за которой следуют ровно три символа.
Тест [ -f "$file" ]
возвращает true, только если $file
- обычный файл (не каталог или другой более специализированный тип, например, устройство). В противном случае оператор continue
пропустит остаток этого прохода через цикл for
.
Присвоение переменной dir
выглядит причудливо, но на самом деле это просто взятие содержимого переменной $file
, ее инвертирование, извлечение первых 3 символов (из инвертированной строки), затем повторное инвертирование и присвоение результата в качестве значения $dir
. Другими словами, это последние три символа имени файла.
Затем, mkdir -p
вернет успех, если каталог уже существует, или создаст его, если нет (и вернет успех). Если он не вернет успех, не стоит пытаться перемещать в него файлы! Отсюда и обработка ошибок.
Затем, команда mv
, как обычно.
Замечание об обработке ошибок:
Вы можете увидеть такие конструкции:
mkdir -p "$dir" || echo "Failed, exiting" && exit 1
Это несовершенно, потому что команда exit
выполняется только если команда echo
успешна после сбоя команды mkdir
. Вместо этого вы хотите, чтобы команда exit
выполнялась независимо от того, удалась ли команда echo
, предполагая, что mkdir
не удалась. Вот почему я использую фигурные скобки, как указано выше.
n=0
for filename in shivi11*; do
n=$(( n + 1 ))
mv -i "$filename" "output_$n"
done
... где shivi11*
— шаблон, который должен соответствовать всем файлам, которые вы хотите переименовать (и ничему другому ).
Создайте резервную копию данных и проверьте это.
Ответьте на исходный вопрос(перед его редактированием):
Если вы под «разделить» подразумеваете утилиту split
, то вы можете вызвать утилиту, подобную этой, чтобы получить то, что вы хотите (это предполагает GNU split
и что вы хотели бы разделить файл file
на 20 КБ бит):
split -b 20k -a 1 --numeric-suffixes=1 file output_
Это создает output_1
, output_2
и т. д.
Обратите внимание, что, поскольку мы ограничиваем длину суффикса одним символом с помощью -a 1
, он не сможет быть разделен более чем на 9 файлов. Использование, например. -a 2
создаст файлы с именами output_01
, output_02
и т. д. вплоть до output_99
включительно, но не output_100
.
Опция --numeric-suffixes=1
является специфической для GNUsplit
-опцией, которая выбирает числовые суффиксы, начинающиеся с заданного числа (вместо 0, как при использовании -d
). Обычно split
создает файлы с буквенными суффиксами.