I have some files in my directory. They can be classified into two categories: the files' name pattern in class one are like 1000-24-1-7-1 that have five numbers separated by four dash; the files' name pattern in class two are like abcd-1000-24-1-7-1-efgh-ijkl that are also separated by dash but have letters before or after or both of before and after these numbers.

My question is that how to filter these files in class one out of my directory by moving them into a directory named by first-class.

  • 1
    Are there non-regular files (pipes, directories…) in that directory with that naming scheme? If so, do you want them to be moved, too (Bjorn's and Eric's answers), or do you want them to stay (Don's answer)? – Blacklight Shining Apr 20 '15 at 2:49
  • @BlacklightShining No, these files are all regular. Thanks. – Yulong Ao Apr 20 '15 at 5:49

With some shells, you could use extended globbing+certain flags to match only files in class one.
With bash:

shopt -s extglob
for one in +([0-9])-+([0-9])-+([0-9])-+([0-9])-+([0-9])
        [[ -f $one ]] && mv -- "$one" first-class

+(<PATTERN>) matches one or more occurrences of the given pattern, [[ -f ... ]] tests for regular file - if yes, it's mv-ed to first-class; to perform a dry-run, add echo in front of mv.

With zsh:

setopt extended_glob
mv -t first-class [0-9]##(-[0-9]##)(#c4)(.)

x## matches one or more occurrences of the pattern x, (#cN) requires exactly N matches and (.) matches only files

autoload zmv
zmv -Q '[0-9]##(-[0-9]##)(#c4)(.)' first-class

-Q turns on bare glob qualifiers, to dry-run add -n e.g. zmv -Qn ...

If filtering regular files isn't needed then you can do without the testing in bash:

shopt -s extglob
mv -- +([0-9])-+([0-9])-+([0-9])-+([0-9])-+([0-9]) first-class

and without the (.) qualifier in zsh:

setopt extended_glob
mv -t first-class [0-9]##(-[0-9]##)(#c4)


autoload zmv
zmv '[0-9]##(-[0-9]##)(#c4)' first-class
  • 1
    You don't need zmv; you can setopt extended_glob and use that same glob pattern with plain mv (or any other program, for that matter). Personally, I would use mv with the -t option. – Blacklight Shining Apr 20 '15 at 2:46
  • @BlacklightShining - correct, thanks for the heads-up. – don_crissti Apr 20 '15 at 3:11
  • Also maybe worth noting that the -- tells mv that there will be no further options (thus you can rename a file called -foo with mv -- -foo bar). This means that, in general, you should use -- in scripts; it also means that it's not necessary in this case, because mv will only ever get passed filenames that start with a number. – Blacklight Shining Apr 21 '15 at 2:59
  • @BlacklightShining - yes, I know, check the initial version of my answer. I removed it because, as you said, in general, you should use -- in scripts. – don_crissti Apr 21 '15 at 3:01

Bjorn's solution seems like it should work, but another possibility would be to use find with a regex like find -regextype posix-extended -regex '.*/[[:digit:]]{1,}(-[[:digit:]]{1,}){4}$' then you can use that with either a -exec mv {} first-class \; or pipe to xargs or similar

  • 1
    This will also match files like 2-34 or 44-11-22-000-44-55-7-100 . Maybe if you adjust your regex to match five numbers separated by four dashes, e.g. ".*/[0-9]{1,}(-[0-9]{1,}){4}$". – don_crissti Apr 19 '15 at 14:41
  • Right you are don_crissti, updated to be more precise. I was being sloppy, figuring there weren't a lot of other similar named files there, but that's often a dangerous assumption of course! – Eric Renouf Apr 19 '15 at 14:46

Wouldn't mv [0-9]*-[0-9]*-[0-9]*-[0-9]* first-class do the trick?

  • This won't work OK, it will also move files like 700-24-1-7-1-XYZ and 44h-5c-88-9-2 – don_crissti Apr 19 '15 at 14:36
  • Gah, you're right, this is the usual confusion between wildcard patterns and regexps. [0-9]* in the shell means a digit followed by any number of characters, not 0 or more digits. – Bjorn Munch Apr 19 '15 at 14:44
  • It does not work at all. – Yulong Ao Apr 20 '15 at 1:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.