Accidentally copied files to wrong directory
Piece together solutions available in Stack Exchange.
If you do enough research you will find a solution by combining these five answers:
- How do I compare file names in two directories in shell script?
- How can I remove the first line of a text file using bash/sed script?
- Command to prepend string to each line?
- giving grep output to rm
- How do I make rm not give an error if a file doesn't exist?
Trial Run
First run the command without rm
(remove) option to ensure correct files are being found:
$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}'
/bin/.auto-brightness-config
/bin/auto-brightness-config
/bin/bell
/bin/bell/bell-select-menu
( ... OUTPUT SHORTENED ... )
How it works
find
returns the filenames in Directory 1 (/usr/local/bin
) followed by Directory 2 (/bin
(:
Directory 1 Files in no particular order
- bbbbb
- aaaaa
- yyyyy
Directory 2 Files in no particular order
- echo
- aaaaa
- zcat
- bbbbb
- egrep
- yyyyy
sort
sorts the two directories' filenames alphabetically
- aaaaa
- aaaaa
- bbbbb
- bbbbb
- echo
- egrep
- yyyyy
- yyyyy
- zcat
uniq -d
reports only the duplicates
- aaaaa
- bbbbb
- yyyyy
This gives us a list of Directory 1 filenames that were accidentally copied into Directory 2. But there is a blank line at the top of the list.
tail -n +2
removed the blank line at the top of the list.
awk '{print "/bin/" $0}'
prepends /bin/
to each filename so we have:
- /bin/aaaaa
- /bin/bbbbb
- /bin/yyyyy
Append the rm
command to pipeline
Now that we've confirmed output is correct append the rm
command via xargs
. Note if you have filenames with special characters read the fourth link above for exceptional handling.
$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | xargs rm -f
rm: cannot remove '/bin/.auto-brightness-config': Permission denied
rm: cannot remove '/bin/auto-brightness-config': Permission denied
rm: cannot remove '/bin/bell': Is a directory
rm: cannot remove '/bin/bell/bell-select-menu': Permission denied
The Permission denied
error appears because we must use sudo
powers to run the command. Note the error '/bin/bell' is a directory
. Later we will have to manually removed the directory with rm -d
command.
sudo
powers required for /bin
directory.
The reason permission denied errors occurred is because root
owns the files in /bin
we want to delete and our regular user ID isn't allowed to delete them.
Note depending on how you copied the files into the target directory you may not need need sudo
powers to delete them. For example if you are defined as the owner of the files in the target directory.
Now lets run command with sudo
powers:
$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | sudo xargs rm -f
rm: cannot remove '/bin/bell': Is a directory
rm: cannot remove '/bin/bell/sounds': Is a directory
rm: cannot remove '/bin/startup-scripts': Is a directory
rm: cannot remove '/bin/zap': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/BeOS': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/FreeBSD': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/Linux': Is a directory
75 files have been deleted but 8 empty sub-directories are left to remove. We use the -r
recursive option with rm
command to delete them:
$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | sudo xargs rm -rf
Nothing is reported so no more errors!
Summary
The objective of this answer is to not only solve the problem at hand but show the reader how a problem can be solved by checking multiple existing answers in Stack Exchange.
Your method is great, but looks too long.
While transforming Linux Mint to Ubuntu I have used the command like:
sudo find /bin -type f -exec dpkg -S {} \; 2> ~/Desktop/not-in-apt.out
and as the result for your case we will get wrong copied files list in ~/Desktop/not-in-apt.out
.
You can then review the file and remove files listed in it. Or use some scripting for removal.
To be completely sure that all remaining files in /bin
are normal you can reinstall them by combining dpkg -S /bin
with apt-get install --reinstall
with something like
sudo apt-get install --reinstall $(dpkg -S /bin | sed 's|: /bin||' | sed 's/,//g')