Баш-фрагмент для переміщення всіх файлів у каталозі до цього каталогу


14

У мене є каталог з великою кількістю файлів і каталогів в ньому. Для того, щоб виправити це, я збираюся вкласти всі ці файли в каталог, тому я збирався зробити щось подібне:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Однак це , очевидно , не працюватиме , тому що тоді він буде намагатися рухатися new_directoryв new_directory. Чи є якийсь простий спосіб зробити те, що я хочу, в один рядок, без того, щоб мені потрібно було копіювати та вставляти всі файли та каталоги в цей каталог?


3
він працює, він просто друкує повідомлення про помилку, що він не в змозі перемістити new_directory в себе.
cas

Відповіді:


18

Ваша

mv * ./new_directory
команда насправді спрацює; він просто надрукує попередження про те, що він не може перемістити цей каталог у себе.


«Єдина» проблема з цим полягає в тому, що якщо повне розширення команди стане занадто довгим (тобто занадто багато файлів, занадто довгі імена), це більше не працюватиме.
Niels Basjes

Як бічна примітка, якщо ви збираєтеся це робити з a, git mvви повинні використовувати -kпрапор, оскільки git не вдасться за замовчуванням, а не просто виплюнути попередження. Тож вам потрібно буде робити git mv -k * ./new_dir.
Юваль А

11

Швидкий і брудний oneliner.

mv `ls -A | grep -v new_directory` ./new_directory

1
Не вийде: звичайний ls не буде показувати точкові файли.
wzzrd

Дуже хороший момент. Виправлено це за допомогою -a.

2
Тож замість того, щоб намагатися перенести новий new_directory до себе (Оригінальне запитання), ви зараз намагаєтесь перейти. і .. у new_directory.
Niels Basjes

2
Дякуємо за відгуки Niels. Виправлено його верхнім a, який видаляє. і .. із списку каталогів.

8

Якщо ви просто шукаєте файли (тобто не каталоги), то

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

є найбільш портативним рішенням. Для швидкості вам слід перемістити find і xargs, використовуючи -print0 та -0, але тільки якщо у вас є GNU find та xargs.


3
Використовуючи досить недавню знахідку GNU, ви також можете використовувати \ + замість \; зменшити кількість МВ, які ми робимо.
wzzrd

Якщо ви знайдете GNU, ви також можете використовувати xargs, які будуть робити те саме, і дозволяти вам запускати кілька mvs одночасно зі знаком -p.
Cian

класне використання find- хоча я, безумовно, був у системах, у яких його немає, на жаль :(
warren

Дійсно? find (afaik) вказаний в SUS, тому все повинно мати його. Єдине питання - це GNU find (який має багато приємних крутих варіантів) або звичайний пошук.
Cian


6

Коли я мав цю проблему, я робив одне з наступних:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

або

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

У другій формі використовуються символи пропуску підстановки, які починаються з ".


Я забув пропущені пунктирними файлами макіяжу; дякую за нагадування! :)
aemonge

2

що стосовно:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, не переміщуйте вміст у новий каталог, а вкладайте цей каталог всередину нового.


1

Аналогічно відповіді на відповідь @ Rembrane (хоча це не одноразовий):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Це має бути на 100% портативним - навіть якщо findвін сумно відсутній у вашій системі.


знайти потрібно в єдиній специфікації Unix. Як таке, воно ніколи не повинно бути відсутнім (не те, що ви не могли б щось створити з цього. Але я думаю, це вимагатиме величезних зусиль, і жодна система постачальників цього не бракує)
Cian

можливо, це якісь гіпер-параноїдальні систематичні системи, що приєднуються, або їх еквівалент? не впевнений, але я знаю, що я наткнувся на боксен, у якого його немає :(
warren

1

Мої пропозиції: Як заявили інші

mv * ./new_directory

буде працювати знайти IFF, загальне розширення досить коротке.

Інші мудрі ви можете спробувати цей, який масштабує на набагато більшу кількість файлів:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Пояснення

  1. Список усіх файлів.
  2. Згрупуйте всі назви файлів у шматки максимум 100000 знаків.
  3. Побудуйте одну команду mv на шматок.

перерви, якщо у ваших імен файлів є пробіли
Cian,

Ти маєш рацію. Тому я думаю, що це слід доповнити прапорами -print0 та -0 для виправлення.
Niels Basjes

Я спробував з -print0і -0і це все ще перервами.
Крістіан Цюпіту

find: попередження: ви вказали параметр -maxdepth після аргументу не-параметр -type, але параметри не є позиційними (-maxdepth впливає на тести, визначені перед ним, а також на ті, що вказані після нього). Будь ласка, вкажіть варіанти перед іншими аргументами.
Крістіан Цюпіту

1

Використання:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

На xargsчоловіковій сторінці:

-P max-procs

  Run up to max-procs processes at a time;

-1

Щоб уникнути повідомлення про помилку та зробити це простим:

mv *.* ./new_Folder

зробить те ж саме, але уникайте повідомлення про помилку (якщо я не думаю, що у ваших папках є назви точок, я думаю).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.