В директории удалить все файлы кроме заданных

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Ответить
Аватара пользователя
kt315e
Сообщения: 318
ОС: Debian 11

В директории удалить все файлы кроме заданных

Сообщение kt315e »

Как в текущей директории удалить все файлы кроме заданных? Например директория "/dir1", а неудаляемые файлы "file1", "file2".
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: В директории удалить все файлы кроме заданных

Сообщение t.t »

Не обязательно find

Код: Выделить всё

ls | grep -v '...' | xargs rm
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: В директории удалить все файлы кроме заданных

Сообщение drBatty »

t.t писал(а):
06.09.2013 21:57
Не обязательно find

лучше таки find... Зачем плохому учите?
kt315e писал(а):
20.05.2013 15:45
Как в текущей директории удалить все файлы кроме заданных? Например директория "/dir1", а неудаляемые файлы "file1", "file2".

Код: Выделить всё

find /dir1 ! -name "file[12]" -delete

как-то так.
Это -delete не нужно сразу ставить, лучше сначала без него посмотреть, что получается.

PS: если есть какие-то каталоги, в которые НЕ нужно заходить вообще, используйте -prune

Код: Выделить всё

find /dir1 -path "path_to_exclude" -prune -o ! -name "file[12]" -delete


PS2: обход осуществляется в обратном порядке, каталоги тоже обходятся. И симлинки с хардлинками. Будьте внимательны.

PS3: ещё полезно -empty, которая даёт Ъ, если файл/каталог пуст.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: В директории удалить все файлы кроме заданных

Сообщение t.t »

drBatty писал(а):
06.09.2013 22:07
лучше таки find... Зачем плохому учите?
И чего здесь плохого? При выводе в пайп ls выдаст тот же результат, что и find. Разве что при именах с пробелами потребуется дополнительная обработка.

Да и лишнего написали много. Я думал, любителям sed свойственна чрезмерная лаконичность, а не наоборот. :)
drBatty писал(а):
06.09.2013 22:07
если есть какие-то каталоги, в которые НЕ нужно заходить вообще
drBatty писал(а):
06.09.2013 22:07
обход осуществляется в обратном порядке, каталоги тоже обходятся
kt315e писал(а):
20.05.2013 15:45
в текущей директории
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: В директории удалить все файлы кроме заданных

Сообщение SLEDopit »

UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: В директории удалить все файлы кроме заданных

Сообщение drBatty »

t.t писал(а):
06.09.2013 22:23
И чего здесь плохого? При выводе в пайп ls выдаст тот же результат, что и find. Разве что при именах с пробелами потребуется дополнительная обработка.

плохо то, что ls не обладает никакими способами обхода. Да и выдавать нормальные имена она умеет через... Неинтуитивно (через --quoting-style=WORD, а вот как вы ЭТО будете пихать в rm, это ещё один отдельный вопрос...
t.t писал(а):
06.09.2013 22:23
Да и лишнего написали много. Я думал, любителям sed свойственна чрезмерная лаконичность, а не наоборот. :)

а я думал, что даже фанатеги микроскопа всё равно не станут рекомендовать забивать своим тотемом гвозди. (:

На самом деле -- я пробовал. Способ с ls|sed|rm тупо не нужен, ибо тупо неудобен. ИМХО.
t.t писал(а):
06.09.2013 22:23
в текущей директории

каталог ./d1/d2/d3/d4/ тоже "в текущей директории". Разве не так?

ещё PS: для задания глубины find умеет -maxdepth и -mindepth, а ls не умеет (только -R умеет)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: В директории удалить все файлы кроме заданных

Сообщение t.t »

drBatty писал(а):
06.09.2013 22:51
каталог ./d1/d2/d3/d4/ тоже "в текущей директории". Разве не так?
Строго говоря, нет. Он в директории d1/d2/d3/

SLEDopit писал(а):
06.09.2013 22:28
t.t
почему так не очень хорошо делать (:
Конкретно насчет find-а согласен. Да и то только при обработке самим find-ом либо -print0 | xargs -0

А насчёт for, видимо, осталась привычка со старых версий bash, где конструкция "for f in *" и пробелы-то нормально не обрабатывала - в этом смысле надо переучиваться. (:
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: В директории удалить все файлы кроме заданных

Сообщение drBatty »

t.t писал(а):
06.09.2013 23:56
Строго говоря, нет. Он в директории d1/d2/d3/

строго говоря d1 тоже файл, и его тоже надо удалять. Почему нет?
t.t писал(а):
06.09.2013 23:56
Да и то только при обработке самим find-ом либо -print0 | xargs -0

ну а зачем вообще имя передавать? Лишняя сущность это всегда источник ошибок ИМХО.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: В директории удалить все файлы кроме заданных

Сообщение t.t »

drBatty писал(а):
07.09.2013 06:31
строго говоря d1 тоже файл, и его тоже надо удалять. Почему нет?
Вы знаете людей, которые всерьез называют каталоги файлами? Я таких не встречал.

drBatty писал(а):
07.09.2013 06:31
ну а зачем вообще имя передавать? Лишняя сущность это всегда источник ошибок ИМХО.
Конкретно в этом случае согласен. В более сложных это может быть гораздо меньшим источником ошибок, чем нагромождения скобок и вызовы subshell-ов внутри самого find-а.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
QWERTYASDF
Сообщения: 989
Статус: Чайник со свистком
ОС: GNU/Linux

Re: В директории удалить все файлы кроме заданных

Сообщение QWERTYASDF »

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

директория "/dir1", а неудаляемые файлы "file1", "file2".


Код: Выделить всё

rm /dir1/*[^file1,file2]

И все...
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: В директории удалить все файлы кроме заданных

Сообщение t.t »

Шаблоны работают с символами, а не со строками:

Код: Выделить всё

1 $ touch 1 2 3 11 12 21 31
1 $ ls
1  11  12  2  21  3  31
1 $ ls *[^1]
12  2  3
1 $ ls *[^12]
3
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4455
Статус: GNU generation
ОС: Debian GNU/Linux

Re: В директории удалить все файлы кроме заданных

Сообщение Rootlexx »

Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: В директории удалить все файлы кроме заданных

Сообщение drBatty »

t.t писал(а):
07.09.2013 13:44
Вы знаете людей, которые всерьез называют каталоги файлами? Я таких не встречал.

а я такого каждый день наблюдаю. В зеркале.

Да и вообще считаю, что называть каталоги файлами -- это такое Дао, которое просто необходимо пройти, если не хочешь всю жизнь прозябать в криво поставленном кем-то маздае.

Как всегда, ВСЁ выше(и ниже) изложенное == МХО.
t.t писал(а):
07.09.2013 13:44
Конкретно в этом случае согласен. В более сложных это может быть гораздо меньшим источником ошибок, чем нагромождения скобок и вызовы subshell-ов внутри самого find-а.

а по моему опыту сложная команда find работает быстрее, и изменять её удобнее. Даже в том случае, если её результат -- список файлов, который потом как-то иначе обрабатывается.

И да, субшеллы внутрь find я-бы не рекомендовал пихать. Их можно и снаружи организовать ввиде конвейера.

В итоге, по моему опыту, если нужно выполнить сложную задачу из серии "взять файлы по сложному условию и выполнить сложное действие над ними" лучше выполнять таким кодом:

Код: Выделить всё

FIND_CMD="find здесь создаётся очень сложная команда"
eval "$FIND_CMD" >$FILE_LIST
while read LINE; do
  # здесь обрабатывается один из файлов
done <$FILE_LIST

А ваш конвейер == write-only макароны, который можно написать один раз, и больше НИКОГДА не трогать. Ибо проще с нуля переписать, чем исправить.

Ну лично для меня так.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: В директории удалить все файлы кроме заданных

Сообщение drBatty »

QWERTYASDF писал(а):
07.09.2013 23:12
[^file1,file2]

[:символьный класс:] работает с символами, а не со строками. Т.е. например

расширяется во все имена файлов, которые НЕ начинаются на "d" и не начинаются на "l" и не начинаются на "u".

Потому шаблоны так не умеют. А вот find умеет:
find ! -name "file1" ! -name "file2"

выдаёт именно то, что вы хотите.
Если вам уж так хочется шаблонов, то find и их умеет

Код: Выделить всё

find . -regextype posix-extended ! -regex "\./(file1|file2)"

(такое жуткое regextype нужно для того, что-бы было более понятным RE. В скриптах это не имеет значения, а в одностроках от руки это не нужно)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Ответить