Ответы:
Вот простое решение, которое вы, вероятно, должны использовать:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
В .keep
расширении нет ничего особенного , это просто делает так, чтобы имя файла временно не заканчивалось .gif
.
Если вы не должны переименовать файл (и есть скриптовые ситуации , когда это важно):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
Или вы можете написать это короче, как это:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Вы можете предпочесть использовать find
вместо этого; он очень мощный, вы можете считать его более читабельным и лучше обрабатывать странные имена файлов с такими же символами, как *
в них .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
Я использовал -not
оператор для удобочитаемости, но если важно соответствие POSIX - если вы не используете GNU find, или это для сценария, который вы собираетесь распространять среди других, или запускать на различных системах - вам следует используйте !
вместо этого оператор:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Одна полезная вещь в find
том, что вы можете легко изменить команду для учета регистра, чтобы она находила и удаляла файлы с такими расширениями, как .GIF
тоже:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Обратите внимание, что я использовал -iname
вместо -name
шаблона поиска, *.gif
но я не использовал его для filename.gif
. Предположительно, вы точно знаете, как называется ваш файл, и -iname
будут совпадать с заглавными буквами не только в расширении , но и в любом месте имени файла.
Все эти решения удаляют только файлы, находящиеся непосредственно в текущем каталоге . Они не удаляют файлы, не содержащиеся в текущем каталоге, и не удаляют файлы, которые находятся в подкаталогах текущего каталога.
Если вы хотите удалить файлы везде, содержащиеся в текущем каталоге (то есть в подкаталогах и в подкаталогах этих подкаталогов и т. Д. - файлы, содержащиеся в текущем каталоге или любом из его потомков), используйте find
без maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
Будьте осторожны с этим!
Вы также можете установить другие значения с помощью -maxdepth
. Например, чтобы удалить файлы в текущем каталоге и его дочерних элементах и внуках, но не глубже:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
Просто убедитесь, что вы никогда не ставите на -delete
первое место, прежде чем другие выражения! Вы увидите, я всегда ставлю -delete
в конце. Если вы поместите его в начале, он будет оценен первым, и все файлы в нем .
(включая файлы, не оканчивающиеся на .gif
и файлы в глубоких подподчиненных ... каталогах .
) будут удалены!
Для получения дополнительной информации обратитесь к страницам справочника bash
и sh
и для команд , используемых в этих примерах: mv
, rm
, [
, и (особенно) find
.
find
, который очень универсален.
find
обрабатывать странные имена файлов, *
чем в цикле for? Цикл for *
хорошо обрабатывает файлы , потому что вы использовали двойные кавычки.
Если вы используете bash
(оболочка по умолчанию), extglob
опция оболочки позволяет вам использовать расширенный синтаксис сопоставления с образцом. Чтобы включить его, используйте shopt
встроенную команду:
shopt -s extglob
(Я включил эту строку в мой .bashrc
файл.)
Помимо прочего, он предоставляет доступ к !()
оператору, который соответствует любому шаблону, не входящему в состав скобок. Для вашей цели:
rm !(filename).gif
Более подробная информация доступна в man bash
разделе «Сопоставление с образцом».
extglob
должна быть включена, но ничего плохого не произойдет, если он отключен (в этом случае это просто не работает). И, кажется, он включен по умолчанию, хотя у меня нет ни shopt -s extglob
одного из моих (или глобальных) файлов конфигурации. Если есть простое объяснение того, почему это работает для меня из коробки, вы можете добавить его к этому ответу; или я могу опубликовать новый вопрос.
Откройте терминал с помощью Ctrl+ Alt+ Tи введите:
find . -type f -name "*.gif" -and -not -name "filename.gif" -exec rm -vf {} \;
Разница между -delete
и -exec rm -vf {} \;
заключается в том, что со вторым параметром вы сможете увидеть, какие файлы были удалены из-за -v
флага. Это то, что не может быть сделано с -delete
опцией. ( -name -delete
напечатает имена файлов, но rm
с -v
показом, если каждый файл был успешно удален.)
Там GLOBIGNORE
переменная. От man bash
:
GLOBIGNORE
A colon-separated list of patterns defining the set of filenames
to be ignored by pathname expansion. If a filename matched by a
pathname expansion pattern also matches one of the patterns in
GLOBIGNORE, it is removed from the list of matches.
Итак, простой способ - просто указать GLOBGINORE
имя файла, о котором идет речь:
$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png
Итак, в вашем случае:
GLOBIGNORE=filename.gif; rm *.gif
Конечно, поскольку он GLOBIGNORE
содержит шаблоны, вы можете использовать его, когда хотите исключить шаблон:
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
(?!) Преимуществом GLOBIGNORE
является то , что установка автоматически исключает .
и..
от подкрепляются, и это позволяет dotglob
:
The GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern. If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches. The filenames ``.'' and ``..'' are always ignored
when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option, so
all other filenames beginning with a ``.'' will match. To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*'' one
of the patterns in GLOBIGNORE. The dotglob option is disabled when
GLOBIGNORE is unset.
Итак, простой способ удаления всех файлов и папок в каталоге:
GLOBIGNORE=.; rm -r *
*
Будет соответствовать имена файлов , начинающиеся с .
, так как GLOBIGNORE
включен dotglob
, но он не будет соответствовать .
или ..
, так что вы не будет влиять на родительский каталог , что путь.