Move all files except one on Linux


If you're working with Linux, there might be times when you'll want to copy several files at once and then remove some of them later. We're going to take a closer at several different methods for achieving such results.

Renaming The Unwanted File

You can rename the unwanted file so that it becomes a “.” (dot) file means hidden files, which means that mv won't be able to see it. After renaming the unwanted file using the asterisks, we’ll then use the regular expression to remove the rest of the files.

/source_dir$ mv file5 .file5
/source_dir$ mv * ~/target_dir/
/source_dir$ ls -la
total 0
drwxrwxr-x  2 ubuntu ubuntu  60 Jun 10 03:42 .
drwxr-xr-x 21 ubuntu ubuntu 520 Jun 10 03:25 ..
-rw-rw-r--  1 ubuntu ubuntu   0 Jun 10 00:57 .file5

Once we've moved the files, we can now renames the hidden file back to its original filename.

/source_dir$ mv .file5 file5

Using The Exclamation Negation Format

The second method involves using an exclamation mark (!) as a preface for the unwanted file name, enclosed within parentheses. This tells the operating system to look for any other file but the specified file.


We'll first want to run the shopt -s command to set up our ~/.bashrc configuration file. This tells Linux to expand paths when they're used in commands.

$ set shopt -s extglob .bashrc
$ mv source_dir/!(file5) target_dir/

Using an Inverted ls Search

To remove the unwanted file from our system, we simply use the ls command with the -I option. This command displays all other files except for those you specify. This command statement is executed inside an enclosed backtick command. The mV command moves the result of an enclosing operation into the target directory (or files) −

/source_dir$ mv `ls -I file5` ~/target_dir/

Instead of backticks, we can enclose using a sub-shell −

/source_dir$ mv $(ls -I file5) ~/target_dir/

We can also use the output of the command ls -l unwanted_file | grep -v '^d' to transfer the results of the inverted file name query to the target directory.

/source_dir$ ls -I file5 | xargs -i mv {} ~/target_dir/

Using an Inverted Grep Search

This technique uses ls to display the source directory's content and pipes it through the command line tool called "grep". The grape command uses the unwanted file as its index to show all other files. Backticking encloses and evaluates this entire pipeline. After that, the mv command moves the file names from the backticks enclosed operation into the target directory.

/source_dir$ mv `ls | grep -v file5` ~/target_dir/

As an alternative to backticks, we can enclose using a sub-shell −

/source_dir$ mv $(ls | grep -v file5) ~/target_dir/

You can also pipe the output of grep -v 'invert' into an xargs -i command, which moves the results of the inverse search to the target folder.

/source_dir$ ls | grep -v file5 | xargs -i mv {} ~/target_dir

Using sed Search and Replace

To remove a specific unwanted text string from a large number of files, use backticks (`) to enclose a sed command that searches for the unwanted text and then pipes the output of that search into another sed command that removes the unwanted text. After that, the mv command moves the results of listed files to the target directory.

/source_dir$ mv `echo * | sed s:file5::g` ~/target_dir/

As an alternative to backticks, we can enclose using a sub-shell −

 /source_dir$ mv $(echo * | sed s:file5::g) ~/target_dir/

You can also use xargs to run the sed command through the pipeline by including curly braces ({}) between xargs and mv. You need to expand that string so that mv can evaluate it. Curly brackets (brackets) are used to evaluate the new content.

/source_dir$ echo * | sed s:file5::g | xargs -i {} mv {} ~/target_dir/


We've covered several ways to copy files from one location to another, but there are some exceptions. In the beginning, we took a literal approach and renamed the unwanted files in an invisible text document. Later, we checked out using exclamations and carets to determine the unwanted files.