Перемістити всі файли, крім одного


155

Як я можу перемістити всі файли, крім одного? Я шукаю щось на зразок:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

де я переміщую старі речі до нових, крім папки Tux.png. ! -знак являє собою заперечення. Чи є якийсь інструмент для роботи?

Відповіді:


142

Якщо ви використовуєте bash і встановлено параметр extglobоболонки (як правило):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
У мене виникла щось не так, коли я тестував команду для багатьох елементів: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Це випорожнює весь Старий -директорія. Що не так?
Лео Леопольд Герц 준영

5
@UnixBasics, спробуйте: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
Juliano

@Juliano Дуже класна команда! Чи є більше математичних операцій, таких як АБО і XOR? Я припускаю, що труба призначена для AND.
Лео Леопольд Герц


@Juliano Я досить заплутаний у таких моделях: mv ~ / Linux /? (Tux * .png) ~ / Linux / New / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / У колишньому , Я хотів перемістити 0-1 Tux -фото. В останньому я хотів перенести 1-н фотографії Tux. Вони рухалися щосили. Чому? Чи можливо перемістити конкретну кількість фотографій?
Лео Леопольд Герц 준영

97

Покладіть наступне на свій .bashrc

shopt -s extglob

Він розширює регекси. Потім ви можете перемістити всі файли, крім одного

mv !(fileOne) ~/path/newFolder

Винятки стосовно інших команд

Зауважте, що при копіюванні каталогів флеш-передача не може бути використана в імені, як помічено в потоці. Чому extglob, крім порушення, крім умови? :

cp -r !(Backups.backupdb) /home/masi/Documents/

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


3
Це насправді правильна відповідь. Міна була неправильною; на щастя, я використав його в папці з лише кількома файлами. Ось додаткова інформація про метод, який показує Масі: wiki.bash-hackers.org/syntax/pattern Перейдіть до "Мова розширеного шаблону", і ви дізнаєтесь більше про це. Дякуємо @ paul-whittaker за вказівку на проблему.
міморалія

Це стара відповідь, але вона все ще діє. Я використовую Ubuntu 18, і extglob, здається, включений за замовчуванням (я не робив цього). Я використовував таку команду для переміщення всіх файлів у поточному каталозі в архів, який також знаходиться в цьому каталозі, НЕ включаючи жодних інших папок архіву: mv !(arc*) archive_190629b
TonyG

70

Я б пішов традиційним способом пошуку & xargs:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1змушує не рекурсивно шукати. Якщо ви дбаєте лише про файли, можете сказати -type f. -mindepth 1змушує не включати ~/Linux/Oldв результат сам шлях. Працює з будь-якими іменами, у тому числі з тими, що містять вбудовані нові рядки.

В одному коментарі зазначається, що -tопція mv - це, ймовірно, розширення GNU. Для систем, які цього не мають

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Оновлений, оскільки це заохочує вивчити потужний інструмент, знайти. Зауважте, для файлів з пробілом ця робота не працює. Розглянемо "find -print0 | xargs -0" або інше forego xargs: "знайди [те, що ти сказав] -exec mv -t {} ~ / Linux / New \;"
JasonSmith

Якщо ваша команда mv не має опції -t, використовуйте або "find ... -exec mv {} Linux / New \;" або "знайти ... | xargs -I {} mv {} Linux / New". Опція -t здається розширенням GNU, що добре для Linux, але, мабуть, не в іншому місці.
Роб Кеннеді

привіт, ой, я не вдається. я якось подумав, що xargs розділився на нові рядки, але не на пробіли. схоже, я переплутав це з "прочитаним" :) погано виправити
Йоганнес Шауб - ліб

Велике спасибі за чудову пораду! Я збирався вибрати що-небудь, тому що це націлене на питання. Однак згодом я можу відчути корисність ваших команд, тому я мушу вибрати спосіб "знайти і xargs". Це просто скелі. Дякую :)
Лео Леопольд Герц 준영

Шлях до складного. Відповідь Масі є більш повною, простішою і тому правильнішою
user637338

30

Швидким способом було б змінити назву файлу tux, щоб ваша команда переміщення не відповідала.

Наприклад:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

не використовуйте " . ", оскільки це буде переміщувати лише файли, які мають "." в імені. Досить лише «*».
Джуліано

1
Якщо змінити його на *, він також видалить ваш перейменований файл.
Джон Т

6
@John T: Ні, * glob не відповідає файлам, які починаються з крапки.
Білл Карвін

Це найкраща відповідь на сьогоднішній день. Не потрібно змінювати чи коментувати цю відповідь. 100 балів. Дуже дякую. Молодці!
Стів К

23

Я думаю, що найпростіший спосіб зробити це з backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Редагувати:

Замість цього використовуйте зворотний нахил з ls, щоб запобігти використанню його з псевдонімом, тобто здебільшого ls називається як ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Дякую @Arnold Roa


1
Чи можете ви поясніть, чому ви grep -vтам використовуєте ?
Лео Леопольд Герц 준영

1
-v варіант grep виключає результат, це як взяти все, крім Tux.png
Rohail Abbas

1
Це, звичайно, інтуїтивно, але відповіді вище є кращими. Наприклад, якщо ви пишете сценарій, це вимагатиме, щоб ви
знаходились

@nJGL Ми також можемо дати абсолютний шлях тут, я використав homedirectory (~), оскільки у цього питання було
Rohail Abbas

@RohailAbbas Ярмарок досить. ✌️
nJGL

14

Що стосується баш, то, що відповідь правильна. Ось синтаксис zsh (моя оболонка вибору):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Потрібен EXTENDED_GLOBпараметр оболонки.


3
Що робити, якщо ми хочемо виключити два файли?
1717 року

13

Я вважаю, що це трохи безпечніше і простіше розраховувати на прості кроки, які виключають певні файли чи каталоги.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Це найкраще рішення для Busybox / ASH
Stuart Cardall

1
Це спрацювало для мене в ситуації, коли мені довелося перемістити всі файли, крім кількох папок, в інший каталог
Umar Hayat

-lВаріант lsвключатиме в себе багато неактуальною інформації в командному рядку і привести до виходу з ладу команди мв.
jdhao

5

Наведене нижче не є 100% гарантованим методом, і його взагалі не слід намагатися використовувати для сценаріїв. Але іноді це досить добре для швидкого використання інтерактивних оболонок. Файл файлів, як глобус

[abc]*

(який буде відповідати всім файлам з іменами, що починаються з a, b або c) можна заперечити, вставивши спочатку символ "^", тобто

[^abc]*

Я іноді використовую це для невідповідності каталогу "втрачено + знайдено", наприклад, наприклад:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Звичайно, якщо є інші файли, починаючи з l, я повинен потім їх обробити.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Команда find перераховує всі звичайні файли, а команда fgrep викреслює будь-який Tux.png. Повернення наказує mv переміщувати отриманий список файлів.


4
Ніколи, ніколи, не оцінюйте пошук як аргументи для іншої команди. Погані речі трапляться. Можливо, ви щойно створили вразливість. Завжди використовуйте знахідку -print0 | xargs -0 побудувати, або знайти -exec.
Джуліано

3

Як щодо переміщення всього в папці, а потім просто переміщення Tux.png назад?

Я не можу придумати жоден синтаксис оболонки, щоб сказати "все, окрім ...".


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Ця команда, здається, відсутня одна частина, і не працює на моєму комп’ютері. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/працює замість цього.
Кетрін Чен


3

Можна пропустити греп так:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

Це може бути простіше і легко запам'ятовується, і це працює для мене.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

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