Большинство изображений на сетчатке оканчиваются на @2x.png и обычно имеют обычный .png в той же папке. Итак, каков был бы самый быстрый способ найти и удалить file.png (рекурсивно), только если file@2x.png существует в той же папке?

1
Actually 20 Фев 2016 в 11:59

3 ответа

Лучший ответ

Я почти уверен, что это возможно с каким-то запутанным find -exec, но я не могу этого понять. Однако это работает для моих небольших тестов:

$ find -maxdepth 1 -name '*@2x.png' | sed 's/@2x//' | xargs echo rm

Это находит все файлы, оканчивающиеся на @2x.png в текущем каталоге (-maxdepth 1), sed удаляет бит @2x и выводит rm и имя файла. Чтобы действительно удалить их, должно быть xargs rm; чтобы не получать подсказки, используйте rm -f, а из соображений осторожности используйте rm -i.

1
Benjamin W. 20 Фев 2016 в 09:47

Это должно делать:

find /path/to/folder -name '*@2.png' -type f -exec bash -c 'f=${0%@2.png}.png; [[ -f $f ]] && echo rm -- "$f"' {} \;

Или, чтобы ограничить количество порожденных процессов bash:

find /path/to/folder -name '*@2.png' -type f -exec bash -c 'for i; do f=${i%@2.png}.png; [[ -f $f ]] && echo rm -- "$f"; done' _ {} +

Обратите внимание, что эти команды ничего не удаляют, а просто выводят на стандартный вывод команду rm, которая будет выполнена. Удалите echo перед rm, если вам это нравится.

0
gniourf_gniourf 20 Фев 2016 в 12:02

Вы можете использовать подстановку параметров , чтобы проверить файл без @2x и удалить файл, содержащий @2x, примерно так:

#!/bin/bash

while read -r line; do
    printf "found '%s' -> rm '%s'\n" "${line/@2x}" "$line"
    # [ -f "${line/@2x}" ] && rm "$line"
done < <(find "$1" -type f -name "*@2x.png")

Пример использования / вывода

$ bash retinadel.sh dat
found 'dat/tmp/first.png' -> rm 'dat/tmp/first@2x.png'
...

( примечание: код ожидает $path в качестве первого аргумента, и в настоящее время в нем есть комментарий rm, поэтому вы можете протестировать его перед фактической попыткой удаления. Всегда проверяйте наличие резервное копирование перед удалением ценных файлов ...)

note2: вам следует добавить тест в начало скрипта, чтобы проверить хотя бы 1 ввод для пути. например.:

[ -z "$1" ] && {  ## validate at least one argument provided
    printf "error: insufficient input, usage: %s path\n" "${0##*/}"
    exit 1
}

Таким образом, в случае, если пользователь (вы) не предоставил path в качестве аргумента, вы получите:

$ bash retinadel.sh
error: insufficient input, usage: retinadel.sh path
2
David C. Rankin 20 Фев 2016 в 09:19