В директории удалить все файлы кроме заданных
Модераторы: /dev/random, Модераторы разделов
В директории удалить все файлы кроме заданных
Как в текущей директории удалить все файлы кроме заданных? Например директория "/dir1", а неудаляемые файлы "file1", "file2".
Re: В директории удалить все файлы кроме заданных
Не обязательно find
Код: Выделить всё
ls | grep -v '...' | xargs rm
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: В директории удалить все файлы кроме заданных
лучше таки find... Зачем плохому учите?
Код: Выделить всё
find /dir1 ! -name "file[12]" -delete
как-то так.
Это -delete не нужно сразу ставить, лучше сначала без него посмотреть, что получается.
PS: если есть какие-то каталоги, в которые НЕ нужно заходить вообще, используйте -prune
Код: Выделить всё
find /dir1 -path "path_to_exclude" -prune -o ! -name "file[12]" -delete
PS2: обход осуществляется в обратном порядке, каталоги тоже обходятся. И симлинки с хардлинками. Будьте внимательны.
PS3: ещё полезно -empty, которая даёт Ъ, если файл/каталог пуст.
Re: В директории удалить все файлы кроме заданных
И чего здесь плохого? При выводе в пайп ls выдаст тот же результат, что и find. Разве что при именах с пробелами потребуется дополнительная обработка.
Да и лишнего написали много. Я думал, любителям sed свойственна чрезмерная лаконичность, а не наоборот. :)
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Re: В директории удалить все файлы кроме заданных
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.
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: В директории удалить все файлы кроме заданных
плохо то, что ls не обладает никакими способами обхода. Да и выдавать нормальные имена она умеет через... Неинтуитивно (через --quoting-style=WORD, а вот как вы ЭТО будете пихать в rm, это ещё один отдельный вопрос...
а я думал, что даже фанатеги микроскопа всё равно не станут рекомендовать забивать своим тотемом гвозди. (:
На самом деле -- я пробовал. Способ с ls|sed|rm тупо не нужен, ибо тупо неудобен. ИМХО.
каталог ./d1/d2/d3/d4/ тоже "в текущей директории". Разве не так?
ещё PS: для задания глубины find умеет -maxdepth и -mindepth, а ls не умеет (только -R умеет)
Re: В директории удалить все файлы кроме заданных
Строго говоря, нет. Он в директории d1/d2/d3/
Конкретно насчет find-а согласен. Да и то только при обработке самим find-ом либо -print0 | xargs -0
А насчёт for, видимо, осталась привычка со старых версий bash, где конструкция "for f in *" и пробелы-то нормально не обрабатывала - в этом смысле надо переучиваться. (:
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: В директории удалить все файлы кроме заданных
строго говоря d1 тоже файл, и его тоже надо удалять. Почему нет?
ну а зачем вообще имя передавать? Лишняя сущность это всегда источник ошибок ИМХО.
Re: В директории удалить все файлы кроме заданных
Вы знаете людей, которые всерьез называют каталоги файлами? Я таких не встречал.
Конкретно в этом случае согласен. В более сложных это может быть гораздо меньшим источником ошибок, чем нагромождения скобок и вызовы subshell-ов внутри самого find-а.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 989
- Статус: Чайник со свистком
- ОС: GNU/Linux
Re: В директории удалить все файлы кроме заданных
Я извиняюсь конечно, может чего не поняла, но зачем так сложно? Ведь оболочка распознает шаблоны...
И все...
директория "/dir1", а неудаляемые файлы "file1", "file2".
Код: Выделить всё
rm /dir1/*[^file1,file2]
И все...
Re: В директории удалить все файлы кроме заданных
Шаблоны работают с символами, а не со строками:
Код: Выделить всё
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нεиж
Спасибо сказали:
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: В директории удалить все файлы кроме заданных
а я такого каждый день наблюдаю. В зеркале.
Да и вообще считаю, что называть каталоги файлами -- это такое Дао, которое просто необходимо пройти, если не хочешь всю жизнь прозябать в криво поставленном кем-то маздае.
Как всегда, ВСЁ выше(и ниже) изложенное == МХО.
а по моему опыту сложная команда find работает быстрее, и изменять её удобнее. Даже в том случае, если её результат -- список файлов, который потом как-то иначе обрабатывается.
И да, субшеллы внутрь find я-бы не рекомендовал пихать. Их можно и снаружи организовать ввиде конвейера.
В итоге, по моему опыту, если нужно выполнить сложную задачу из серии "взять файлы по сложному условию и выполнить сложное действие над ними" лучше выполнять таким кодом:
Код: Выделить всё
FIND_CMD="find здесь создаётся очень сложная команда"
eval "$FIND_CMD" >$FILE_LIST
while read LINE; do
# здесь обрабатывается один из файлов
done <$FILE_LIST
А ваш конвейер == write-only макароны, который можно написать один раз, и больше НИКОГДА не трогать. Ибо проще с нуля переписать, чем исправить.
Ну лично для меня так.
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: В директории удалить все файлы кроме заданных
[:символьный класс:] работает с символами, а не со строками. Т.е. например
Код: Выделить всё
[^dlu]*
расширяется во все имена файлов, которые НЕ начинаются на "d" и не начинаются на "l" и не начинаются на "u".
Потому шаблоны так не умеют. А вот find умеет:
find ! -name "file1" ! -name "file2"
выдаёт именно то, что вы хотите.
Если вам уж так хочется шаблонов, то find и их умеет
Код: Выделить всё
find . -regextype posix-extended ! -regex "\./(file1|file2)"
(такое жуткое regextype нужно для того, что-бы было более понятным RE. В скриптах это не имеет значения, а в одностроках от руки это не нужно)