Как переместить все родственные папки в одну папку?

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

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

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

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

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

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

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

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

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

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

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

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

cd foo
mv * bar

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

5 ответов

Решение

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

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

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

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

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

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

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

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

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

Да, вы правы, это было бы проблемой, потому что * также будет соответствовать 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

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

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

CD в ​​Foo

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

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

mv -t bar oops*
Другие вопросы по тегам