Як видалити кілька файлів одночасно в Bash на Linux?


103

У мене є цей список файлів на сервері Linux:

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

Я вилучав окремі файли журналів по одному за допомогою команди rm -rfдив. Нижче:

rm -rf abc.log.2012-03-14
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

Чи є інший спосіб, щоб я міг видалити вибрані файли відразу?


4
І "Скажи GNU / Linux, а не тільки Linux", я чую, як гріне сомон із задніх сидінь.
Борис Стітнікі

8
До речі, навіщо -rf? Це папки? f - сила, r - для рекурсивної. Він буде працювати, якщо це лише файл, але будьте попереджені, використовуючи -rf кожен раз, коли ви хочете щось видалити, це дуже (дуже) (дуже дуже) небезпечно. (і вам слід додати тег "bash", оскільки "linux" занадто широкий.
Depado

@BorisStitnicky - Мені цікаво, навіщо GNUце потрібно?
user66001

2
@ user66001: Висновок проекту GNU з цього питання: gnu.org/gnu/linux-and-gnu.html . Я не займаю жодної позиції з цього приводу, принаймні не тут, і це не місце для його обговорення.
Кіт Томпсон

2
@BorisStitnicky - Не потрібно дискутувати, був абсолютно незрозумілим, і це посилання дало мені рівень інформації, який я шукав +1
user66001

Відповіді:


159

Bash підтримує всілякі підстановки та розширення.

Ваш точний випадок вирішуватиметься шляхом розширення дужок , як-от так:

$ rm -rf abc.log.2012-03-{14,27,28}

Вищезазначене розшириться до однієї команди з усіма трьома аргументами та було б еквівалентно введенню:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

Важливо зауважити, що це розширення робиться оболонкою, перш ніж rmнавіть завантажується.


Не використовуйте "rm", якщо хочете відновити файли в майбутньому. Ви можете скористатися утилітою "rm-trash": github.com/nateshmbhat/rm-trash
Natesh bhat

75

Використовуйте підстановку ( *), щоб зіставити декілька файлів.

Наприклад, команда нижче видалить усі файли з іменами, що починаються з abc.log.2012-03-.

rm -f abc.log.2012-03-*

Я рекомендую запустити ls abc.log.2012-03-*список файлів, щоб ви могли бачити, що ви збираєтесь видалити перед запуском rmкоманди.

Більш детально див. Сторінку "Bash man" про розширення імені файлу .


Дуже корисно, але видавати підтвердження не потрібно. Будьте в курсі.
nuriselcuk

1
@nuriselcuk ви можете додати -i, щоб отримати підтвердження для кожного видаленого файлу.
Феліпе Ромеро

Працював як шарм на AWS Ec2-Instance під керуванням Amazon Linux 1 :) Дякую.
Kyle Bridenstine

41

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

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

Регулярні вирази є більш потужними, ніж маклери; Ви можете подати вихід grepна rm -f. Наприклад, якщо деякі імена файлів починаються з "abc.log"деяких, а деякі з "ABC.log", grepдозволяють вам збігтися до невідповідності регістру:

$ rm -f $(ls | grep -i '^abc\.log\.')

Це спричинить проблеми, якщо будь-яке ім’я файлів містить смішні символи, включаючи пробіли. Будь обережний.

Коли я це роблю, ls | grep ...спершу запускаю команду і перевіряю, чи видає я потрібний результат, особливо якщо я використовую rm -f:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

де !!розгортається до попередньої команди. Або я можу набрати стрілку вгору або Ctrl-P і відредагувати попередній рядок, щоб додати rm -fкоманду.

Це передбачає, що ви використовуєте оболонку bash. Деякі інші оболонки, зокрема csh та tcsh, а також деякі старі оболонки, отримані sh, можуть не підтримувати $(...)синтаксис. Ви можете використовувати еквівалентний синтаксис backtick:

$ rm -f `ls | grep -i '^abc\.log\.'`

$(...)Синтаксис легше читати, і якщо ви дійсно амбітні це може бути вкладеним.

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

$ ls > list
$ vi list   # Use your favorite text editor

Потім я можу редагувати listфайл вручну, залишаючи лише ті файли, які я хочу видалити, а потім:

$ rm -f $(<list)

або

$ rm -f `cat list`

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

Або, редагуючи listфайл, я можу додати rm -f до початку кожного рядка, а потім:

$ . ./list

або

$ source ./list

Редагування файлу - це також можливість додавати лапки, де це необхідно, наприклад, змінюючи rm -f foo barна rm -f 'foo bar'.


8

Просто використовуйте підбірку рядків піднесене, щоб об'єднати всі файли в один рядок і додати пробіл між кожним іменем файлу, а потім додати rmна початку списку. Це в основному корисно, коли у файлах файлів, які ви хочете видалити, немає шаблону.

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10

Це має бути прийнятою відповіддю, оскільки вона чітко відповідає на поставлене питання. Це більш привітно до людей, які приїхали сюди з Google.
ATLief

5

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

rm -rf abc.log.2012-*

Хоча, як виглядає це, це лише одні файли? Рекурсивний варіант не повинен бути необхідним, якщо жоден із цих предметів не є каталогами, тому краще не використовувати це, лише для безпеки.


2

Я не є гуру Linux, але я вважаю, що ви хочете передати свій список вихідних файлів xargs rm -rf. Раніше я використовував щось подібне з хорошими результатами. Спершу тестуйте у зразковому каталозі!

EDIT - Можливо, я зрозумів неправильно, грунтуючись на інших відповідях, які з’являються. Якщо ви можете використовувати подвійні картки, чудово. Я припускав, що ваш оригінальний список, який ви показали, був сформований програмою, щоб дати вам "вибір", тому я подумав, xargsщо шлях до маршруту - це шлях.


-1

якщо ви хочете одразу видалити всі файли, що належать до каталогу. Наприклад: ім'я вашого каталогу - це "log", а "log" каталог включає файли abc.log.2012-03-14, abc.log.2012-03-15, ... тощо. Ви повинні бути над каталогом журналів і:

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