I'm currently having an assignment that wants me to copy a select amount of files. More specifically files that are even using the cp command. The assignment is to copy files that start with cp and are even. This was my command at first cp[24680]* but it returned all files that had an even number in it. I just want files that end in the even number.

example I want to copy only these files:
cp1250.enc cp1256.enc cp852.enc cp864.enc cp932.enc
cp1252.enc cp1258.enc cp860.enc cp866.enc cp936.enc
cp1254.enc cp850.enc cp862.enc cp874.enc cp950.enc.

But the command I make gives me :
cp437.enc cp852.enc cp857.enc cp861.enc cp863.enc cp865.enc cp869.enc
cp850.enc cp855.enc cp860.enc cp862.enc cp864.enc cp866.enc cp874.enc

Dani AI

Generated

Good catch by : your first glob was not anchoring the even digit at the end. If you want only files that start with cp, then a run of digits, and end with an even digit just before .enc, require digits after cp and constrain the last digit:

# preview matches safely, then copy
printf '%s\n' cp[0-9]*[02468].enc
mkdir -p even
cp -- cp[0-9]*[02468].enc even/

Why it works: in Bash globs, [02468] matches exactly one even digit, and [0-9]* insists that what follows cp is a sequence of digits (so names like cpabc2.enc will not match). See Bash’s bracket expressions and glob rules for details. Bash pattern matching. If you do not want the literal pattern to be passed when there are no matches, enable nullglob first: shopt -s nullglob. The shopt builtin (nullglob).

If you prefer a regex-based approach (useful when you later need more control), find can match the entire path using -regex. Example with POSIX ERE and a literal dot before the extension:

find . -type f -regextype posix-extended \
  -regex '.*/cp[0-9]*[02468]\.enc$' -exec cp -t even -- {} +

Note that -regex matches the whole pathname, so the pattern above includes .* before cp and ends with $ to anchor the extension. Switch to -iregex if case-insensitivity is needed. find -regex (whole-path matches) explained.

’s wildcard idea was on the right track; tightening it to demand digits after cp prevents false positives and guarantees the last character before .enc is even.

Recommended Answers

All 2 Replies

What about:
cp*[24680].enc or cp*[24680].* ?

So if the files are all in the current directory and you want to copy the even numbered ones to a sub-directory called "even" you could do the following:
Using cp (or mv):
cp ./cp*[24680].enc ./even/
or
cp ./cp*[24680].* ./even/

or using the find command:
find ./ -type f -iname "cp*[24680].*" -execdir cp {} ./even/ \;

EDIT:
Note: Unless you specify a maxdepth for find, it will look for files recursively in any sub-directories, which you might not want it to do.
To make it only search in the current directory you can do this:
find ./ -maxdepth 1 -type f -iname "cp*[24680].*" -execdir cp {} ./even/ \;

Your example gets those that start with an even number, not the ones that have an even number at the end of the number string. IE, it will properly return "cp2.enc" as well as "cp4.enc", "cp6*.enc", etc. So, that would include "cp211.enc" and such.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.