Copy all except one file linux

copy entire directory excluding a file

As we know, cp -r source_dir intended_new_directory creates a copy of source directory with a new name. Now I want to do the same but want to exclude a particular file. I have found some related answers here, using tar and rsync, but in those solutions I need to create the destination directory first (using mkdir).
I honestly searched a lot, but didn’t find exactly what I want.
So far the best I got is this:

tar -c --exclude=\*.dll --exclude=\*.exe sourceDir | tar -x -C destDir 

4 Answers 4

If you have binutils, you could use find to filter next cpio to copy (and create directories) :

find \( ! -name *.dll \) -a \( ! -name *.exe \) | cpio -dumpv

Try this by excluding the file using ‘grep -v’ ->

Here @dganesh2002 copies all the files from the current directory to the destination directory. OK if there are no subdirectories, filenames don’t have spaces, and number of files in the current directory is not too large.

thanks much to dganesh2002 and @atycnth. Though I still need to create the dest_dir myself, I like this solution because its mechanism is simple, and I can easily remember it.

If the directory is not very large I used to write something like this:

src=path/to/source/directory dst=path/to/destination/directory find $src -type f | while read f ; do mkdir -p "$dst/`dirname $f`"; cp "$f" "$dst/$f" ; done 

Here we list all regular files in $src , iterate over this list and for each file make a directory in $dst if it does not exist yet ( -p option of mkdir ), then copy the file to that directory.

The above command will copy all the files. Finally, just use

find $src -type f | grep -v whatever | while . # same as above 

to filter out the files you don’t need (e.g. \.bak$ , \.orig$ , or whatever files you don’t want to copy).

Источник

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.

$ mv SOURCE_DIRECTORY/!(unwanted_filename) TARGET_DIRECTORY

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/

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/

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/

Conclusion

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.

Читайте также:  Linux intel uhd 630

Источник

How to copy some, but not all files?

So, you can use the * as a wild card for all files when using cp within context of a directory. Is there a way to copy all files except x file?

7 Answers 7

Rsync handles this nicely.

Example copy all: rsync -aP /folder1/* /folder/2

Example copy all with exclusion: rsync -aP —exclude=x /folder1/* /folder2/

On darwin/MacOS, use -rP instead of -aP if you want to recurse. -a is for archiving. Not sure if this changed or if it’s just different on MacOS.

rsync does have the option to make it recursive. Example: rsync —recursive -P —exclude=x /folder1/* /folder2/ . (Tested only on Ubuntu)

In bash you can use extglob :

 $ shopt -s extglob # to enable extglob $ cp !(b*) new_dir/ 

where !(b*) exclude all b* files.

You can later disable extglob with

Unfortunately I don’t. Seems like find is the only way in tcsh : find . -maxdepth 1 ! -name «exclude*» -exec cp -t destination <> \+

This isn’t a feature of cp , it’s a feature of your shell (it expands the * to mean all non-dot files), so the answer depends on which shell you’re using. For example, zsh supports this syntax:

Where ^x means «all files except x «

You can also combine selection and de-selection patterns, e.g. to copy all wav files except those containing xyz, you can use:

Could also be done in plain old (portable/compatible) bourne shell in a variety of ways with standard tools in a lot less elegant ways than using advanced shell globbing or commands with built-in-exclusion options.

If there are not too many files (and not with names including spaces and/or linebreaks), this could be a way:

cp `ls | egrep -v '^excludename$'` destdir/. 

Sure, bash and GNU tools are great and powerful, but they’re still not always available. If you intend to put it in a portable script, I would recommend find as in the comment by Rush.

Читайте также:  Установка русского языка linux mint

Источник

BASH copy all files except one

I would like to copy all files out of a dir except for one named Default.png. It seems that there are a number of ways to do this. What seems the most effective to you?

Why do you need it to skip that file, as opposed to just deleting it after copying it? Does it exist in the target directory already?

@LasseV.Karlsen: Or you could want to save the time of copying it, if it’s a large file. I’m interested in this but excluding a directory rather than a file.

9 Answers 9

If copying to a folder nested in the current folder (called example in the case below) you need to omit that directory also:

cp -r !(Default.png|example) /example 

It seems that OS X needs to use shopt -s extglob as described by @BarryKelly. With that, it works perfectly.

Years on Bash and didn’t know about !() . Beautiful! For those that —like me— feel it is time to study/review bash, here are the relevant links related to this question/answer: shopt/extglob and the pattern.

rsync has been my cp/scp replacement for a long time:

rsync -av from/ to/ --exclude=Default.png -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X) -v, --verbose increase verbosity 

multiple —exclude= arguments are supported. And don’t forget the -r arg if you’re syncing directories

this»rsync -aP —exclude=backup /root/jenkins_api/* /root/jenkins_api/backup» does not work when there is no files in /root/jenkins_api/**.Is there a workaround to skip when no files are found ?

Simple, if src/ only contains files:

find src/ ! -name Default.png -exec cp -t dest/ <> + 

If src/ has sub-directories, this omits them, but does copy files inside of them:

find src/ -type f ! -name Default.png -exec cp -t dest/ <> + 

If src/ has sub-directories, this does not recurse into them:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ <> + 

@Max \; executes the command once per file. + runs the command once and passes all of the file names to it at once (subject to the command line length limit). + is a bit more efficient in general.

cp `ls | grep -v Default.png` destdir 

@arthur.sw For one thing, it doesn’t account for files with spaces in it. As with many things with the shell, there’s a bunch of edge cases that fail. 95%+ of the time, this stuff just works. Just need to be conscious of the caveats. Spaces in file names jump working with the shell from trivial to painful.

Читайте также:  Linux ubuntu сменить пароль root

Another reason is that since there are no anchors in the regex and the dot isn’t escaped it would also match a file named myDefaultXpng.OLD for example.

cp srcdir/* destdir/ ; rm destdir/Default.png 

unless the files are big. Otherwise use e.g.

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/ 

The first command is not what the OP asked for. If Default.png exists in the two directories, it will replace the one in destdir by the one in srcdir , then delete the copied Default.png . Instead, the OP wants to keep the Default.png that already exists in destdir .

Jan, 2022 Update:

This is the easiest way(It’s not complicated).

First, make «temp» folder:

Second, copy all files from your original folder to «temp» folder:

«-R» flag can copy exactly all files including «Symbolic Links»

Third, remove «Default.png» from «temp» folder:

Finally, copy all files from «temp» folder to your destination folder:

cp -R temp/. destinationFolder/ 

In addition, this is the shortest way without «temp» folder:

cp -R originalFolder/!(Default.png) destinationFolder/ 

Below script worked for me

cp -r `ls -A | grep -v 'skip folder/file name'` destination 
# chattr +i /files_to_exclude # cp source destination # chattr -i /files_to_exclude 

use the shell’s expansion parameter with regex

Everything will be copied except for the not_to_copy_file

— if something is wrong with this. please Specify !

Welcome to SO. Unfortunately your answer is not correct. The bracket expresssion ( [. ] ) contains a set of characters to match, while a leading ^ will cause a match of the complement of the listed characters. In the following example, neither file will be listed: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]* because all filenames starting with any of the following characters will be excluded: _cefilnopty .

Источник

Оцените статью
Adblock
detector