конвейерный вывод команды find

конвейерный вывод команды find

В дополнение к моему запросу, опубликованному - Использование find с sh - команда не работает

На основании приведенной ниже команды мне необходимо обновить разрешение до 777 для каждого из перечисленных файлов.

find . -type f -name '*FW*' -exec grep -iEq 'chmod.*archive|archive.*chmod' {} \; -ls

Есть ли способ передать вывод chmodи обновить права доступа к файлам?

решение1

Вы можете добавить еще один -execдля findвыполнения chmodна файлах. Удалите, -lsесли он вам не нужен:

find . -type f -name '*FW*' -exec grep -iEq 'chmod.*archive|archive.*chmod' {} \;\
  -ls -exec chmod 777 {} +

решение2

Вы можете добавить еще один -execв конце, чтобы обновить разрешения для файлов, прошедших предыдущие тесты,как Фредди показывает, или вы можете объединить grepи chmodво встроенном sh -cскрипте:

find . -type f -name '*FW*' -exec sh -c '
    for pathname do
        if grep -q -i -e "chmod.*archive" -e "archive.*chmod" "$pathname"
        then
            chmod 777 "$pathname"
        fi
    done' sh {} +

Это будет использоваться findкак своего рода генератор имен путей для цикла в sh -cскрипте.

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


В bash, вы можете вместо генерации имен путей с помощью find, использовать шаблон подстановки имен файлов:

shopt -s globstar nullglob dotglob

for pathname in ./**/*FW*; do
    if [ -f "$pathname" ] && grep -q -i -e 'chmod.*archive' -e 'archive.*chmod' "$pathname"
    then
        chmod 777 "$pathname"
    fi
done

Единственное видимое отличие здесь в том, что будут обрабатываться также символические ссылки, соответствующие шаблону.

Параметр globstarshell включает **шаблон, который рекурсивно сопоставляется с подкаталогами. nullglobПараметр shell заставляет несовпадающие шаблоны исчезать, а не оставаться неразвернутыми. dotglobПараметр shell заставляет шаблоны сопоставляться со скрытыми именами.

В zshоболочке это можно сократить до

for pathname in ./**/*FW*(.ND); do
    if grep -q -i -e 'chmod.*archive' -e 'archive.*chmod' $pathname
    then
        chmod 777 $pathname
    fi
done

... где ., Nи Dсоответствует тесту -f(но не будет соответствовать символическим ссылкам), устанавливая nullglobи устанавливая dotglobв bash, по очереди.

Связанный контент