Finding with ls
: first things first, ls | grep cisco
is a bit verbose, since cisco
isn't a regular expression. Try:
ls *cisco*
Using find
: along the same lines, -regex
is overkill with a simple, static pattern. How about:
find -name '*cisco*'
The quotes are required so the glob is interpreted by find
, not the shell. Also, -print
is required for many versions of find
, but is optional (and the default predicate) for others (e.g. GNU find
). Feel free to add it if you need it.
If you need to search for ‘cisco’ in the full pathname, you could try this:
find -path '*cisco*'
which is equivalent to find | fgrep cisco
.
Using find
with regular expressions: let's do that anyway, since this is what you want. Shamelessly copying from the GNU find
manpage:
-regex pattern
File name matches regular expression pattern. This is a match
on the whole path, not a search. For example, to match a file named
`./fubar3', you can use the regular expression `.*bar.' or `.*b.*3',
but not `f.*r3'.
What this means is that your regular expression is wrapped in an invisible ^...$
, so it must match every character in the full pathname of the file. So, as nwildner and otokan said in the comments, you should use something like:
find -regex '.*cisco.*'
And you don't even need the -regextype
for something this simple.
You can do a for loop on the find result and copy the folder with -R :
IFS=$'\n'
for source_folder in "$(find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; |
awk -F"\t" '$NF>=5{print $1}');" do
if [[ "$source_folder" != "." ]]; then
cp -R "$source_folder" /destination/folder
fi
done
Best Answer
As you're not using
find
for very much other than walking the directory tree, I'd suggest instead using the shell directly to do this. See variations for bothzsh
andbash
below.Using the
zsh
shellThe globbing pattern
./**/*(-.D[1,1000])
would match all regular files (or symbolic links to such files) in or under the current directory, and then return the 1000 first of these. The-.
restricts the match to regular files or symbolic links to these, whileD
acts likedotglob
inbash
(matches hidden names).This is assuming that the generated command would not grow too big through expanding the globbing pattern when calling
mv
.The above is quite inefficient as it would expand the glob for each collection. You may therefore want to store the pathnames in an array and then move slices of that:
To randomise the
pathnames
array when you create it (you mentioned wanting to move random files):You could do a similar thing in
bash
(except you can't easily shuffle the result of a glob match inbash
, apart for possibly feeding the results throughshuf
, so I'll skip that bit):