I copied some file from source folder into destination folder by using bellow command line in terminal.
sudo cp From_SOURCE/* To_DESTINATION/
Now I want to undo this command.
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityIf I understand well, the following is the case:
The script below looks in the original (source) directory and lists those files. Then it looks into the directory you copied the files to, and removes only the listed files, as they exist in the source directory.
The try
element is added to prevent errors, for example in case you might have removed some files manually already, or if not all files from the source directory were copied to the destination. If you need sudo privileges, simply run the script with "sudo" (see below).
#!/usr/bin/env python
import os
source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to
for root, dirs, files in os.walk(source_dir):
for name in files:
try:
os.remove(target_folder+"/"+name)
except FileNotFoundError:
pass
reverse.py
,Run it by the command:
[sudo] /path/to/reverse.py
First try on a test directory if I understood well what you need to achieve!
In case the source directory has no sub-directories, the script can even be simpler:
#!/usr/bin/env python
import os
source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to
for file in os.listdir(source_dir):
try:
os.remove(target_folder+"/"+file)
except FileNotFoundError:
pass
Note
If the copy action overwrote (replaced) a similarly named file in the destination, the file will be removed, but the original file will (of course) not be brought back by the script. The assumption is that there are no name clashes.
sudo python3 reverse.py
. I accept your answer.
cp
.
Aug 30, 2014 at 4:57
cp -r
. I changed os.remove
with print
, and it's outputting a bunch of files that does not exist. I'm assuming it's missing the subdirectories, and only listing the files at the end.
All files that are present in both src
and dest
can be removed from dest
like this:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
For a step-by-step, explanation, see below.
To understand what the command we want to undo actually did, we start by simpifying it:
The command we want to undo is
sudo cp From_SOURCE/* To_DESTINATION/
For understanding how to undo, sudo
is not relevant.
I'll use the directory names src
for From_SOURCE
and dest
for To_DESTINATION
.
Now, our command is:
cp src/* dest/
If src
contains the files f1
, f2
and f3
, and the directories d1
and d2
, the shell expands that command to:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
Without options like -r
, -R
or -a
, the command cp
does not copy directories.
That means, the command will leave them out, showing an error for each of them:
$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'
That means, we have only copied simple files, and no directories, to dest
.
Possibly there were files in dest
of the same name as files in src
. In this case, the files were overwritten (1). It's too late for them, sorry. Get them back from the latest backup.
Regarding the files that are there, we want to remove only files that have been copied over. These files exist in both directories, with the same name, and the same content.
So we look for these files:
First, we cd
into src
, because it makes the following find
commands much simpler, and set a variable to the absolute path of dest:
$ cd src
$ destdir="$(readlink -f dest)"
Then, we list all files in src:
$ find . -maxdepth 1 -type f
and, for each file found, use cmp
to check whether there is a file with the same content in dest:
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print
These files are the ones we want to remove. But to be sure, we move them into a different directory first - and take a look at the commands before running them:
$ toDelete=/tmp/toDelete ; mkdir -p "$toDelete"
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec echo mv -n "$destdir/{}" "$toDelete"/ \;
mv -n /path/to/dest/./f1 /tmp/toDelete/`
mv -n /path/to/dest/./f2 /tmp/toDelete/`
mv -n /path/to/dest/./f3 /tmp/toDelete/`
Looks good! Now we can leave out the echo
to run the real mv
commands:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
All the files from dest
that were copied from src
, and still actually the same in src
and dest
, are now in /tmp/toDelete/
, and can be removed after taking a last look.
Notes:
(1) Check whether cp
is an alias to cp -i
or so, that would have prevented overwriting files by asking first.
This is old, but I just wanted to post a pure bash answer:
First change to the directory where you copied the files.
cd dest
Then, ls
the source directory and pipe the output into rm
ls source | xargs rm
ls
is typically a bad idea. mywiki.wooledge.org/ParsingLs I won't downvote your post, but it has to be noted.
Jul 17, 2016 at 9:53
rm `ls`
—for an empty beforehand folder and when the files have names without spaces and newlines.
From_SOURCE/*
, and remove those fromTo_DESTINATION/
; this could be done with bash - the problems here could include cp command overwrote anything, symlinks were copied, files with spaces in names, etc - so it could have issues and go a bit wacky. A perfect 'undo' option could would have to account for lots of stuff.