How do I move some but not all files from one directory to another?
Solution 1
If you have bash and don't care about also matching files like apple.not-a-number
, try
shopt -s extglob
mv apple.!(0) /new/directory
Solution 2
if you're using bash you should be able to use
mv apple.[^0]* /other/directory/
this will move any files of which the extension does not start with 0 ( "^" at the beginning of [ ] means "not" in bash). If you're sure there's only one character as an ending you could also use
mv apple.[^0] /other/directory/
and if you have to make sure only files which end in numbers you could use
shopt -s extglob
mv apple.@([1-9])*([0-9]) /other/directory/
this would not match apple.01 or similar though....
and a last one which should get all the apple files ending in numbers
shopt -s extglob
mv apple.*([1-9]|[0-9]+([0-9])) /other/directory/
Solution 3
To be as specific as you want on the file to move and not to move
find /source/directory -maxdepth 1 -name "apple.*" ! -name "apple.0" -exec mv {} /new/directory \;
Olgun Kaya
Updated on September 18, 2022Comments
-
Olgun Kaya almost 2 years
I need to move my files from one directory to other. But there is some issues. My file name pattern is like:
apple.0, apple.<n>, n -> {0,1,2,3 ...~ }
so
mv apple.*
will not work, because I need to keep apple.0, which is always the active one.How do I move them with exceptions (in this case, keeping apple.0)?
-
Olgun Kaya almost 13 years
bash: !: event not found
is thrown. -
Olgun Kaya almost 13 yearsI am gonna try
ls
,egrep
andmv
with pipes. -
tcoolspy almost 13 yearsThat won't quite work, you cannot use the
&&
operator to combine these. First you need to run theshopt -s extglob
option to set the shell to use extended globing mode, then you can use that glob pattern. The way this answer is formatted the shell tries to do the globing on the command line before any of the commands (including the one about enabling the option) are run. -
tcoolspy almost 13 years@OlgunKaya: This will work and match your files just like you want if you first run
shopt -s extglob
then in any following command or later in your script use that pattern. -
jw013 almost 13 years@Caleb Thanks, you are right. I've fixed it but Marcel's answer is still the better one.
-
Chris Perkins almost 13 yearsCool. I didn't know bash supported regexes. :)
-
tcoolspy almost 13 years@MarcelG's answer is good, but because of the character class it is limited to single character exclusions. This extended glob pattern can be extended to be multiple-characters as well as other patterns. It's good to know about both.
-
tcoolspy almost 13 yearsIf you did want to combine these into a single command and not change the option in your current shell you would need to invoke a sub-shell.
(shopt -s option ; command [...])
-
jw013 almost 13 yearsTechnically globs aren't quite normal regex. The glob
[1-9][0-9]*
will actually match any pattern that begins with two digits in the range 10-99 followed by anything, e.g. 23apples would match. -
Marcel G almost 13 yearsI got something mixed up (regex vs. globs/expansions as balki and jw023 point out) :-) the last option does not what I explained it does... so I fixed it with new options based on the solution by jw0123.
-
Vishwanath Dalvi almost 13 years@balki bash and regexes are like husband and wife.
-
Gilles 'SO- stop being evil' almost 13 yearsWith
extglob
, you get the power of regexps but in a wildcard syntax. The zsh analog to these bash commands is to usesetopt ksh_glob
instead ofshopt -s extglob
, or to usesetopt extended_glob
thenmv apple.*~apple.0 /other/directory/
.