How do I move all the files with the same name scattered through the file system into one folder?
I can think of two possible solutions:
If you have installed
mv
from GNU coreutils (which probably is the case), then the following command...find / -name "HAHA" -type f -exec mv --backup=numbered "{}" /home \;
...will move all files called
HAHA
to/home
. The--backup=numbered
option ofmv
ensures that every time themv
command executes, it will check if there already exists a file namedHAHA
in the target directory -- and if it does, then it first renames it toHAHA.~n~
(wheren
is an increasing number) before moving the new file to the/home
. In the end, you will end up with files named likeHAHA
,HAHA.~1~
,HAHA.~2~
etc. in/home
.This shell script should do the trick, but it is not resistant against paths containing newlines:
IFS=" " # if you are using bash, you can just use IFS=$'\n' here i=1 for file in $(find / -name "HAHA" -type f); do mv "${file}" "/home/HAHA${i}" i=$((${i} + 1)) done
This iterates over all the
HAHA
files and moves each one to/home/HAHAn
, wheren
again is an increasing number, starting with 1.
I found a simple solution with a small script. The script is called cpf
(or whatever name you give it) and is as follows:
#!/bin/bash
dir=xyz # Directory where you want the files
num=1
for file in "$@"
do
base=`basename -- "$file"`
mv -- "$file" "$dir/$base.$num"
num=$(($num+1))
done
You execute the command as follows:
find . -name HAHA -print0 | xargs -0x cpf
I would use while
loop:
i=1
find / -name 'HAHA' -print0 | while read -d '' -r file; do mv "$file" "/home/${file##.*/}$((i++))"; done
Important here is print0
option of find
which (together with -d ''
option of read
) treats properly files with white spaces in their names. If you need to do such operation only once then first line which sets i=1
is not needed since bash
(and most of other shells) will simply created this variable automatically.