6

Я извиняюсь, что это кажется таким тупым вопросом, но я не могу позволить себе все испортить.

У меня есть несколько папок, таких как:

/ Пользователей / меня / Foo / oops1

/ Пользователей / меня / Foo / oops2

/ Пользователей / меня / Foo / oops3

/ Пользователей / меня / Foo / oops4

/ Пользователей / меня / Foo / бар

К сожалению, они не имеют одинакового названия, и существуют сотни папок с сообщениями.

Я намеревался скопировать все папки oops в панель. Есть ли простой способ переместить все папки oops в панель, которые не приведут к какой-либо проблеме рекурсивного перемещения?

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

Кстати, на RedHux Linux-сервере. У меня есть только доступ по SSH.

Я думаю, что если я сделаю

cd foo
mv * bar

будет проблема.

5 ответов5

7

То, что вы предлагаете, совершенно верно. mv достаточно умен и скажет так:

mv: cannot move `bar' to a subdirectory of itself, `bar/bar'

Тем не менее, все ваши oopsx dirs будут внутри бара.

3

К сожалению, как ответ Мэтта, так и ответ Николь демонстрируют плохой стиль и сломаются, если любая из папок даже содержит один символ пробела, символ слияния (как *) или символ новой строки. Запуск for item in $(ls …) - огромная ошибка, которую можно совершить, потому что он рано или поздно укусит их, а перебор имен файлов, неправильный вывод их может вызвать всевозможные проблемы.

Никогда не анализируйте вывод ls.

В Linux есть инструмент для поиска файлов, соответствующих определенным критериям, и он называется find:

find . -mindepth 1 -maxdepth 1 \
-type d ! -regex ".\/bar$" \
-exec mv '{}' ./bar/ \;

Это переместит любые каталоги в текущем рабочем каталоге, которые не называются bar в ./bar/ . Это будет работать, даже если имена каталогов содержат пробелы, символы-заглушки или символы новой строки.

Регулярное выражение .\/bar$ будет соответствовать только каталогу с именем ./bar , и оно отменяется ! ,

3

Да, вы правы, это было бы проблемой, потому что * также будет соответствовать bar ; Вы не можете mv каталог в себя.

Обидчивый способ заключается в использовании команды замены и петли на mv только те вещи , которые не bar Например, в bash вы можете написать что-то вроде этого, но учтите, что произойдет сбой, если попадет в имя, содержащее пробел (потому что подстановка команд разбивает вещи на слова в пробелах).

mv $(for i in *; do if [ $i != "bar" ]; then echo $i; fi; done) bar

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

cd foo
mv bar ../bar.save
mv * ../bar.save
mv ../bar.save bar
1

Если, если вы чувствуете себя в большей безопасности, вы можете сделать это в BASH:

for item in `ls -d | grep -v "^bar$"`; do mv $item bar; done;
-1

CD в Foo

mv -t bar oops[[:digit:]]

из более общего

mv -t bar oops*

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