The assignment can be interpreted in three ways:
- Copy all
.c
and .h
files from the current directory to the directory Programs
, or
- Copy all
.c
and .h
files from the current directory or anywhere below it to the directory Programs
.
- Copy all accessible
.c
and .h
from anywhere on the system to the directory Programs
.
Note that the assignment says "copy", not "move". This means that you should be using the cp
command, not mv
.
The first interpretation of the assignment is solved by
cp *.[ch] Programs
(assuming that *.[ch]
matches all files we're interested in, and there's not many thousands of these in the current directory).
The second interpretation of the assignment is solved by
find . -path ./Programs -prune -o -type f -name '*.[ch]' -exec cp {} Programs \;
This searches for all regular files with a .c
or .h
filename suffix in or below the current directory, and executes cp
for each such file. We can't pipe to cp
since that utility does not read its standard input stream.
We also make sure to avoid looking inside the Programs
directory (assumed to be a subdirectory in the current directory). Not doing that would end up copying files from Programs
into Programs
. See "Explain find's -path and -prune options" for more info about -path
and -prune
.
The third interpretation is easy to implement from the second:
find / -path "$PWD/Programs" -prune -o -type f -name '*.[ch]' -exec cp {} Programs \;
... we just need find
to start at the top of the directory tree and to specify that the Programs
directory to avoid is the one at the path $PWD/Programs
.
This will likely throw a number of errors at you due to you not having access everywhere. To avoid this, also prune directories that you can't access and only copy files that you can read:
find / \( -type d ! -executable -o -path "$PWD/Programs" \) -prune -o \
-type f -name '*.[ch]' -readable -exec cp {} Programs \;
This requires GNU find
for the -executable
test (a directory is searchable if it's executable) and the -readable
test.
Note that the find
variations here will restrict the files to only regular files (through the -type f
test), while the cp *.[ch]
approach would copy any type of thing that ends in those two characters. Also, the find
solution would copy hidden files (files with names that begin with a dot), while the first solution would not match those types of names by default.