Рейтинг:6

Моя команда `find` в скрипте не находит файлы и каталоги с пробелами в именах

флаг pr

Некоторое время назад я написал скрипт, который перемещает файлы и каталоги из Загрузки к .Загрузки если они старше 3 дней, и удалить их из этого каталога через 30 дней. Он работает нормально, но только для файлов без пробелов.

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

Вот что найти делает:

найти вывод команды

Я ожидал увидеть найти Команда также находит файлы с пробелами.

Вот сценарий:

#! /бин/баш
# установить -х
экспорт ДИСПЛЕЙ =: 0,0

# true - удалить, иначе - переместить
функция процесса () {
    если [ "$2" = "УДАЛИТЬ" ]; тогда
        rm -r "$1" && notify-send "$3 $1 удалено!"
    еще
    mv "$1" "../.Downloads/$1" && notify-send "$3 $1 перемещено в ~/.Downloads/$1!"
    фи
}

# удалить пустые каталоги
для пустого каталога в `find ~/Desktop/ ~/Downloads/ -empty -type d`; делать
    notify-send "Directoy $emptyDir был удален, т.к. был пуст!"
сделано
найти ~/Рабочий стол/ ~/Загрузки/ -пусто -тип d -удалить

# удалить/переместить старые файлы/директории
если [ -z "$1" ] || [ "${1,,}" != "удалить" ] && [ "${1,,}" != "переместить" ]; тогда
    echo "Указать режим параметра (удалить/переместить)"
    выход
фи

если [ "${1,,}" == "удалить" ]; тогда
    день=30
    путь=".Загрузки"
    режим = "УДАЛИТЬ"
еще
    день=2
    путь = "Загрузки"
    режим = "ПЕРЕМЕЩЕНИЕ"
  кр  
  если [ ! -d "~/.Загрузки" ]; тогда
    mkdir -p ~/.Загрузки
  фи
фи

компакт-диск ~/$путь

для элемента *
делать
    если [-d "$элемент"]; тогда
        если [$(find "$element" -type f -mtime -$day | wc -l) -eq 0 ]; тогда
            процесс "$element" "$mode" "Directory"
        фи
    еще
        если [ $(find `pwd` -name "$element" -mtime +$day | wc -l) -gt 0 ]; тогда
            процесс "$element" "$mode" "Файл"
        фи
    фи
сделано

Прошу Вас подсказать, что я могу делать не так.

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

GammaGames avatar
флаг in
Вы можете поместить что-нибудь простое, например `@reboot [имя пользователя] find ~/Downloads/ -mtime +3 -exec gio trash {} \;` в свой crontab. Мой дистрибутив настроен на стирание файлов мусора через 30 дней, но это также можно сделать вручную с помощью пакета `trash-cli`.
Рейтинг:13
флаг hr

Вкратце: это не пробелы, это скобки1

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

Бывший.

$ touch 'имя файла с [квадратными скобками] внутри'
$ найти . -name 'имя файла с [скобками] в нем'
$

(никаких результатов - потому что [скобки] означает любой одиночный символ в наборе б, р, а, с, к, е, т, с); тогда как

$ найти . -name 'имя файла, в котором есть \[скобки\]'
./имя файла с [скобками] в нем

Если вам нужно реализовать это программно, вы могли бы использовать оболочку bash printf чтобы добавить необходимые escape-последовательности:

$ element='имя файла с [квадратными скобками] внутри'
$ найти . -name "$(printf '%q' "$element")"
./имя файла с [скобками] в нем

  1. однако у вас БУДЕТ проблема с пробелами в строке

    для пустого каталога в `find ~/Desktop/ ~/Downloads/ -empty -type d`; делать
    

    Видеть Почему зацикливание вывода find является плохой практикой?

  2. есть ряд других вопросов, например цитируемый ~ в [ ! -d "~/.Загрузки" ] не будет расширяться до $ГЛАВНАЯ - вообще следует избегать ~ в сценариях

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.