Расширенная фильтрация файлов

У меня есть 3 разных папки: история, входящие, резервные копии.

Мне нужно скопировать все файлы из «истории» в «Входящие», только если они не присутствуют в «резервной копии».

  • Скопировать файлы из списка в папку
  • Сравнение каждого файла в двух каталогах и копирование его на другой, если он отличается от его аналога
  • Как это сделать?

  • Сравнение каждого файла в двух каталогах и копирование его на другой, если он отличается от его аналога
  • Скопировать файлы из списка в папку
  • 2 Solutions collect form web for “Расширенная фильтрация файлов”

    Просто пример, есть ли какая-либо вложенная папка в истории?

    for x in history/*; do [[ -f backup/"$(basename "$x")" ]] || cp "$x" inbox done 

    Этот скрипт будет циклически перемещаться по всем возможным файлам в папке истории и извлекать базовое имя (например, basename / bin / ls is ls) и проверять, существует ли файл в папке резервного копирования; если нет, выполните процедуру копирования.

    Этот простой скрипт работает только в том случае, если три каталога не содержат подкаталогов (для обработки этого случая потребуется более сложный рекурсивный алгоритм).

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

     #! /bin/sh # use tempfile(1) if available, otherwise use: # EXCLUDEFILE="/tmp/excl.$$" EXCLUDEFILE=$(tempfile -p excl) # generate an exclude file, changing backup/ to history/ find backup/ -type f | sed -e 's:^backup/:history/:' > "$EXCLUDEFILE" find history/ -type f -print0 | \ grep -z -Z -F -v -x -f "$EXCLUDEFILE" | \ xargs -0r -i{} cp {} inbox/ rm "$EXCLUDEFILE" 

    FYI, длинная форма используемых здесь параметров grep:

     grep --null-data --null --fixed-strings --invert-match \ --line-regexp --file "$EXCLUDEFILE" 

    и еще более компактная форма:

     grep -zZFvxf "$EXCLUDEFILE" 

    Большинство вариантов обычно используются или само собой разумеются, но три могут потребовать некоторого объяснения:

    -z или --null-data сообщает grep, чтобы ожидать ввода с нулевым завершением (от find -print0 )
    -Z или --null указывает grep выводить строки с нулевым завершением (для xargs -0 к xargs -0 )
    -x или --line-regexp сообщает grep, чтобы он соответствовал только целым строкам

    Linux и Unix - лучшая ОС в мире.