Move all files except one

LinuxBashGlob

Linux Problem Overview


How can I move all files except one? I am looking for something like:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

where I move old stuff to new stuff -folder except Tux.png. !-sign represents a negation. Is there some tool for the job?

Linux Solutions


Solution 1 - Linux

If you use bash and have the extglob shell option set (which is usually the case):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

Solution 2 - Linux

Put the following to your .bashrc

shopt -s extglob

It extends regexes. You can then move all files except one by

mv !(fileOne) ~/path/newFolder

Exceptions in relation to other commands

Note that, in copying directories, the forward-flash cannot be used in the name as noticed in the thread Why extglob except breaking except condition?:

cp -r !(Backups.backupdb) /home/masi/Documents/

so Backups.backupdb/ is wrong here before the negation and I would not use it neither in moving directories because of the risk of using wrongly then globs with other commands and possible other exceptions.

Solution 3 - Linux

I would go with the traditional find & xargs way:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1 makes it not search recursively. If you only care about files, you can say -type f. -mindepth 1 makes it not include the ~/Linux/Old path itself into the result. Works with any filenames, including with those that contain embedded newlines.

One comment notes that the mv -t option is a probably GNU extension. For systems that don't have it

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

Solution 4 - Linux

A quick way would be to modify the tux filename so that your move command will not match.

For example:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

Solution 5 - Linux

I think the easiest way to do is with backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Edit:

Use backslash with ls instead to prevent using it with alias, i.e. mostly ls is aliased as ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Thanks @Arnold Roa

Solution 6 - Linux

For bash, sth answer is correct. Here is the zsh (my shell of choice) syntax:

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Requires EXTENDED_GLOB shell option to be set.

Solution 7 - Linux

I find this to be a bit safer and easier to rely on for simple moves that exclude certain files or directories.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Solution 8 - Linux

The following is not a 100% guaranteed method, and should not at all be attempted for scripting. But some times it is good enough for quick interactive shell usage. A file file glob like

[abc]*

(which will match all files with names starting with a, b or c) can be negated by inserting a "^" character first, i.e.

[^abc]*

I sometimes use this for not matching the "lost+found" directory, like for instance:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Of course if there are other files starting with l I have to process those afterwards.

Solution 9 - Linux

This could be simpler and easy to remember and it works for me.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

Solution 10 - Linux

This can bei done without grep like this:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

Note: -I is a captial i and makes the ls command ignore the Tux.png file, which is listed afterwards.

The output of ls is then piped into mv via xargs, which allows to use the output of ls as source argument for mv.

ls -Q just quotes the filenames listed by ls.

Solution 11 - Linux

How about:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

You have to be in the folder though.

Solution 12 - Linux

mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

The find command lists all regular files and the fgrep command filters out any Tux.png. The backticks tell mv to move the resulting file list.

Solution 13 - Linux

ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

Solution 14 - Linux

move all files(not include except file) to except_file
find -maxdepth 1 -mindepth 1 -not -name except_file -print0 |xargs -0 mv -t ./except_file
for example(cache is current except file)
find -maxdepth 1 -mindepth 1 -not -name cache -print0 |xargs -0 mv -t ./cache

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLéo Léopold Hertz 준영View Question on Stackoverflow
Solution 1 - LinuxsthView Answer on Stackoverflow
Solution 2 - LinuxLéo Léopold Hertz 준영View Answer on Stackoverflow
Solution 3 - LinuxJohannes Schaub - litbView Answer on Stackoverflow
Solution 4 - LinuxJohn TView Answer on Stackoverflow
Solution 5 - LinuxRohail AbbasView Answer on Stackoverflow
Solution 6 - LinuxJulianoView Answer on Stackoverflow
Solution 7 - Linuxalex.pilonView Answer on Stackoverflow
Solution 8 - LinuxhlovdalView Answer on Stackoverflow
Solution 9 - LinuxPakpoom TiwakornkitView Answer on Stackoverflow
Solution 10 - LinuxArchLinuxTuxView Answer on Stackoverflow
Solution 11 - LinuxantibusView Answer on Stackoverflow
Solution 12 - LinuxDavid NormanView Answer on Stackoverflow
Solution 13 - LinuxaitorView Answer on Stackoverflow
Solution 14 - LinuxmutongView Answer on Stackoverflow