Как в Bash удалить все файлы с одинаковым именем, кроме файла, расположенного в определенной папке?

У меня есть определенный файл, который находится в нескольких каталогах. Обычно я удаляю их все, используя синтаксис:

find . -name "<Filename>" -delete

Однако я хочу сохранить один файл из определенной папки, скажем FOLDER1.

Как мне это сделать с помощью find? (Я хочу использовать find, потому что я использую -print перед -delete, чтобы проверить, какие файлы я удаляю. Я опасаюсь использовать rm, так как существует опасность удаления файлов, которые я хочу сохранить.)

Заранее спасибо.


person schrodingerscat11    schedule 12.08.2015    source источник
comment
Что касается использования find вместо rm, чтобы вы могли сначала использовать -print: ваши опасения разумны, но обратите внимание, что с rm вы можете добиться того же, добавив echo в начале.   -  person ruakh    schedule 12.08.2015
comment
... или, возможно, лучше, чем echo: shopt -s extglob, за которым следует (в отдельной строке, поскольку extglob является опцией парсера): printf '%q ' rm !(FOLDER1)/filename; echo -- таким образом, имена с пробелами, скрытыми символами и т. д. печатаются однозначно, а вывод представляет собой оператор rm, который можно скопировать/вставить обратно в оболочку, не беспокоясь о том, что будет делать имя каталога, включающее литеральную строку $(rm -rf .).   -  person Charles Duffy    schedule 12.08.2015
comment
...конечно, приведенный выше extglob предполагает, что FOLDER1 является непосредственным подкаталогом текущего рабочего каталога и что удаляемые файлы находятся только в одном каталоге; отрегулируйте по своему усмотрению (возможно, запустив shopt -s globstar и используя, например, **/!(FOLDER1)/filename) в противном случае.   -  person Charles Duffy    schedule 12.08.2015


Ответы (2)


Вы можете сделать это с

find . -name "filename" -and -not -path "./path/to/filename" -delete

Вы захотите либо убедиться, что выражение пути является относительным, включая начальное ./, чтобы оно соответствовало выражению, либо использовать подстановочные знаки. Поэтому, если вы знаете, что он находится в папке с именем myfolder, но не знаете полного пути к нему, вы можете использовать

find . -name "filename" -and -not -path "*/myfolder/filename" -delete
person chiastic-security    schedule 12.08.2015

Если вы не хотите удалять ничего в каком-либо каталоге с именем FOLDER1, вы можете указать find вообще не выполнять рекурсию вниз по любому каталогу с таким именем, используя -prune:

find . -name FOLDER1 -prune -o -name filename -delete

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


Примечание: при тестировании убедитесь, что вы используете явный -print:

find . -name FOLDER1 -prune -o -name filename -print

... тогда как неявный не будет вести себя так, как вы ожидаете:

# not what you want: equivalent to the below, not the above:
find . -name FOLDER1 -prune -o -name filename

... будет вести себя как:

find . '(' -name FOLDER1 -prune -o -name filename ')' -print

...который, таким образом, включает содержимое по по обе стороны от оператора -o для действия.

person Charles Duffy    schedule 12.08.2015