1

Further to my query posted - Using find with sh - command not working

Based on the o/p of the below command I need to update the permission to 777 for each of the files that are listed.

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

Is there any way that we can pipe the output to chmod and update file permissions?

Freddy
  • 25,565

2 Answers2

1

You can add another -exec to find to execute chmod on the files. Remove the -ls if you don't need it:

find . -type f -name '*FW*' -exec grep -iEq 'chmod.*archive|archive.*chmod' {} \;\
  -ls -exec chmod 777 {} +
Freddy
  • 25,565
1

You can add another -exec at the end to update the permissions on the files that pass the preceding tests, like Freddy shows, or you may combine the grep and chmod in an inline sh -c script:

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 {} +

This would use find as a sort of a generator of pathnames for the loop in the sh -c script.

This loop takes all pathnames given to the inline script, tests each one with grep, and if the pattern matches in a file, that file gets its permissions (possibly) updated.


In bash, you may, instead of generating the pathnames by find, use a filename globbing pattern:

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

The only visible difference here is that this would also process symbolic links that match the pattern.

The globstar shell option enables the ** pattern that matches recursively into subdirectories. The nullglob shell option makes non-matching patterns disappear instead of remaining unexpanded. The dotglob shell option makes patterns match hidden names.

In the zsh shell, this may be shortened to

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

... where the ., N and D corresponds to the -f test (but won't match symbolic links), setting nullglob and setting dotglob in bash, in turn.

Kusalananda
  • 333,661