2

Дерево моей папки

.
|-- 1
|-- 2
|-- 3
...
|-- 777

Я хотел бы создать папку изображений для каждой папки.

Я бегу безуспешно

mkdir */pictures

Одним из способов, конечно, является создание 777 команд mkdir с регулярным выражением Vim. Тем не менее, я бы знал, как вы можете сделать это в оболочке.

Как вы можете mkdir */pictures?

9 ответов9

8
for x in `seq 1 777`
do
    mkdir $x/pictures;
done

Кроме того, в прошлом вы упоминали zsh и это должно работать без изменений, по крайней мере, под bash и zsh .

7

Почти так же, как другие, но с добавлением слеша, поэтому он считает только каталоги, а не обычные файлы

for x in */
do
    mkdir $x/pictures;
done
2
for i in *; do cd $i; mkdir pictures; cd ..; done

Редактировать: я заметил, что кто-то избил меня, и я немного улучшу скрипт (проверим, является ли он каталогом):

for i in *; do if [ -d $i ]; then cd $i; mkdir pictures; cd ..; fi; done
2

Много способов сделать это, я думаю, это самое простое:

for f in *; do mkdir $f/pictures; done

Это быстро и грязно и создаст подкаталог для всего в вашем текущем каталоге. Вы получите безобидные ошибки, если в текущем рабочем каталоге есть файлы. Если это вас беспокоит, лучше использовать более сложное решение, используя find или seq или тому подобное. Если ваши каталоги пронумерованы, то более простой вариант Seq-примера (в bash)

mkdir {1..777}/pictures

Кстати, mkdir может легко создавать несколько каталогов одновременно:

mkdir 1/pictures 2/pictures

Проблема в том, что */pictures не расширяются ни в какую оболочку, так как каталоги еще не существуют.

1

Мои рекомендуемые решения:

find . -mindepth 1 -maxdepth 1 -type d '(' -exec mkdir -- '{}'/pictures \; -o -exec printf 'Could not create: [[%s/pictures]] ??\n' '{}' \; ')';

или же

(for d in ./* ; do [ -d "$d" ] && { mkdir -- "$d"/pictures || printf 'Could not create [[%s/pictures]]... permissions problem, disk is full?\n' "$d";};done;);

или же

(for d in   * ; do [ -d "$d" ] && { mkdir -- "$d"/pictures || printf 'Could not create [[%s/pictures]]... permissions problem, disk is full?\n' "$d";};done;);

Ниже приведен пример:

(for d in ./* ; do [ -d "$d" ] && { mkdir    "$d"/pictures || printf 'Could not create [[%s/pictures]]... permissions problem, disk is full?\n' "$d";};done;);

Последний вариант будет работать, но я не рекомендую его, здесь показано, как использование ./* вместо * может помочь в некоторых случаях снизить риски, поскольку расширения для ./* будут такими же, как для * но с префиксом с ./ так что они также являются допустимыми путями, и даже если любое из этих значений используется небрежно, как в mkdir "$d"/pictures , это не вызовет проблем (или, по крайней мере, проблем, в зависимости от контекста).

Все они будут работать с именами, содержащими (пробел), табуляция, CR, LF ... ЛЮБОЙ ХАРАКТЕР в именах (кроме / , и это потому, что это не разрешено в именах, только для отделения одного имени от другого в пути и в качестве корневого каталога). Таким образом, в основном, это будет работать с любым путем.

Каждому, кто прочитал ответы, использующие переменные для имен файловых систем: не следуйте этим примерам, во время написания все они ошибочны, и во всех них есть общая проблема: переменные не в кавычках, а в все дела здесь должны. (Если в именах нет проблемных символов, они будут делать то же самое, но даже в этом случае рекомендуется цитировать их).

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

Есть очень немного обстоятельств, при которых не нужно заключать в кавычки переменную оболочки; и во всех них содержимое переменных должно быть проверено трижды, в таких ситуациях вы не можете быть слишком осторожны. Эти обстоятельства очень редки и их можно избежать почти всегда.
Есть исключение из этого: здесь-документы, подстановки внутри них ведут себя так, как они уже процитированы, подстановки внутри подстановок внутри-документов ведут себя как обычно.

(*) Я уже видел, как этот конкретный рак достаточно распространен, и слишком много людей спрашивают, почему команда ломается только в некоторых случаях / путях ... и "помогают", переписывая половину сценария, когда пара " будет исправил оскорбительную линию
Я думаю, что я получу 'Я цитирую переменные и замены, как будто нет завтра!'напечатано на футболке.)


На момент написания и ИМХО нет ни одного приемлемого (приемлемого без возражений) ответа на вопрос, и это недопустимо!
В последней строке вопроса OP спросил, как сделать mkdir */pictures и я принимаю это как петицию за общее решение, которое не делает предположений об именах подкаталогов.

Второй блок кода из ответа Нельсона ( mkdir {1..777}/pictures; ) работает и не содержит ни ошибок, ни плохих практик (если мы не считаем принудительное использование bash одним xD) , но будет работать только в сценарии EXACT, описанном в первой части вопроса, и только в bash или какой-либо другой оболочке, реализующей расширение скобки {n..m} для генерации нескольких аргументов на основе последовательности из одного. Первый кодовый блок в этом ответе заслуживает только игнорирования, это ужасно неправильно.

Тот от mdpc, отредактированный Гаретом , вполне приемлем, почти идеален:

find . -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/pictures \;

несмотря на то, что использование его как есть, может закончиться резней; но это можно сделать идеально, изменив его так, чтобы он выглядел так:

find . -mindepth 1 -maxdepth 1 -type d -exec mkdir -- '{}'/pictures \;

(Это первый в списке решений в моем ответе).
Он включает -- между параметрами (флажками) для mkdir (или самого mkdir ) и аргументом:
Рекомендуется всегда делать это, когда начальный символ первого аргумента не жестко закодирован в команде, чтобы он не пытался проанализировать аргумент как потенциальную опцию (флаг). Это может быть сделано почти со всеми командами (есть несколько исключений, само по себе очевидное).
Обратите внимание, что я цитировал {} , более правильно использовать '{}' или \{\} , так как в этом случае он не будет иметь никакого особого значения для любой оболочки posix, даже дрянной.

Вкратце: только два решения не содержат ошибок, но одно использует "bashism", поэтому не будет работать во многих оболочках, а другое могло бы быть более правильным (недостаточно хорошим, чтобы люди могли правильно выучить сценарий-фу из ), довольно разочаровывает. У меня были слишком большие ожидания, я думаю ...

Я не говорю, что ни один ответ не сработает для сценария ТАК ТОЧНО, большинство сработает, но определенно большинство из них не являются правильным кодом (я не имею в виду синтаксис, не только по крайней мере) и / или включают в себя плохие практики какого-либо (некоторые из них даже настоящие зверства).


Источники: своего рода одержимость стандартами и правильностью кода, а также документация с http://www.opengroup.org/, man dash, man bash и даже Интернет-сайты! : но надежные источники, а не ответы от dont-даже-ноу-хау-процитировать-правильно-парней ... (есть по крайней мере пара ответов, которые выглядят так, как в этом вопросе, без обид, никто не рождается зная все).

1

Как насчет:

find . -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/pictures \;
1

Я собираюсь предположить, что вы используете Bash ...

find . -mindepth 1 -maxdepth 1 -type d | while read dir; do mkdir $dir/pictures; done

или если все в каталоге является каталогом

ls | while read dir; do mkdir $dir/pictures; done

Если вы используете tcsh, вы должны сделать это с неэлегантным циклом for.

1
mkdir ~/Pictures
mkdir ~/container
mkdir ~/container/1
mkdir ~/container/2
mkdir ~/container/3
mkdir ~/container/4
mkdir ~/container/5

cp -r ~/Pictures ~/container/**/
rm -rf ~/Pictures

Это сработает, я только что попробовал

0

Я проверил это, и это должно быть то, что вам нужно:

#!/bin/bash 
list=$(/bin/echo *)

for file in $list
do
    if [ -d $file ]; then
        cd $file
        mkdir picture
        cd ..
        echo "Added folder to $file"
    fi
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .