How do I exclude a folder when performing file operations i.e. cp, mv, rm and chown etc. in Linux
Solution 1
If you're using bash and enable extglob via shopt -s extglob
then you can use !(<pattern>)
to exclude the given pattern.
Solution 2
find dir_to_start -name dir_to_exclude -prune -o -print0 | xargs -0 chown owner
find dir_to_start -not -name "file_to_exclude" -print0 | xargs -0 chown owner
Solution 3
for file in *; do
if [ $file != "file_I_dont_want_to_chown" ]
then
chown -R Camsoft $file
fi
done
Solution 4
Combine multiple small sharp tools of unix: To exclude the folder "foo"
% ls -d * | grep -v foo | xargs -d "\n" chown -R Camsoft
Solution 5
For this situation I would recommend using find. You can specify paths to exclude using the -not -iwhilename 'PATH'. Then using exec you execute the command you want to execute
find . -not -iwholename './var/foo*' -exec chown www-data '{}' \;
Although this probably does help for your situation I have also see scripts set the immutable flag. Make sure you remove the flag when your done you should use trap for this just in case the script is killed early (note: run from a script, the trap code runs when the bash session exits). A lot of trouble in my option but it's good in some situations.
cd /var
trap 'chattr -R -i foo > /dev/null 2>&1' 0
chattr -R +i foo
chown -R www-data *
Camsoft
Updated on July 09, 2022Comments
-
Camsoft almost 2 years
How do you exclude a folder when performing file operations i.e. cp etc.
I would currently use the wild card * to apply file operation to all, but I need to exclude one single folder.
The command I'm actually wanting to use is
chown
to change the owner of all the files in a directory but I need to exclude one sub directory. -
Camsoft over 14 yearsWould that work recursively, drilling down in to sub-directories?
-
SourceSeeker over 14 yearsYou don't need
ls
. Just usefor file in *
-
Camsoft over 14 yearsI've executed the command above. Can you give me an example that uses the !() syntax in combination with chown?
-
SourceSeeker over 14 yearsThe
-0
here accomplishes nothing. -
Camsoft over 14 yearsI'm getting an "File name too long" error when executing the above command. The filename shown in the error seems to be a concatenation of all the files in the directory separated with "\n"
-
Camsoft over 14 yearsUnfortunately the directory I want to exclude is a certs folder and messing the permissions of this up will break our HTTPS requests.
-
Camsoft over 14 yearsThat worked! One more question will the excluded filename be applied recusively, so that if there is a folder or file called foo deeper in the directory tree will that one also be skiped too? I only want to exclude the first foo which is a direct descendent of the top level folder.
-
SourceSeeker over 14 yearsThat's because
ls
is not intended to be used this way. -
Ignacio Vazquez-Abrams over 14 yearsOnly if you use a pattern such as
**/foo
. -
Camsoft over 14 yearsSo like: chown 0755 -R !(**/foo) ?
-
Christopher Bruns over 14 years'-d "\n"' might help. I'm not on a linux box at the moment, so I can't be certain. It works with cygwin.
-
Ignacio Vazquez-Abrams over 14 yearsCorrect, although
**
requires theglobstar
shell option to be enabled (which only exists in bash 4.0), and it doesn't contain foo, so you'd needchown 0755 -R !({foo,**/foo})
. -
Hasturkun over 14 years@Dennis Williamson: actually, it's probably because of the
-0
-
Martin Beckett over 14 yearsFair enough - it's just sometimes the solution is simpler than a complex regex/xargs statement ;-)
-
Volomike almost 14 yearsThis works for me on Ubuntu 10.04 LTS and also CentOS5. I first run that shopt command, cd into the dir I want to adjust, and then run chown with the NOT condition. Works like a charm. Really cool hack!
-
user569825 over 12 yearsAt least for bash an sh you'll need a
do
to logically commence the loop. -
Craig Harshbarger over 7 yearsHow would you do this in a bash script? chown -R 775 !(foo) breaks. I tried !"(foo)" but then it says
no such file or directory
-
Ignacio Vazquez-Abrams over 7 years@CraigHarshbarger: Did you do the first part?
-
Craig Harshbarger over 7 yearsNo, very new to this. Can you give me an example of the full command? Thanks
-
Ignacio Vazquez-Abrams over 7 years@CraigHarshbarger:
shopt -s extglob