Ответы:
Вот простое решение, которое вы, вероятно, должны использовать:
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, но он не будет соответствовать .или .., так что вы не будет влиять на родительский каталог , что путь.