Reputation: 37
I am trying to copy multiple files of the same name from different directories into one and have them not overwrite each other by adding some number before the name. I have a file structure like this, where the image.fits files are different files, but have the same name because they are automatically generated and the parent folder name is also auto generated:
~/Sources/<unknown>/<foldername1>/image.fits
~/Sources/<unknown>/<foldername2>/image.fits
~/Sources/<unknown>/<foldername3>/image.fits
...
Is there a way to copy these files into one folder like this:
~/Sources/<target_folder>/1_image.fits
~/Sources/<target_folder>/2_image.fits
~/Sources/<target_folder>/3_image.fits
Like mentioned above the folder names are also automatically generated, so I want to use some kind of wildcard (*) to access them if possible. The command can either be some command, a shell script or python code, whatever works.
EDIT: The final solution I used is based on the one from @Kasper and looks like this:
import os
import shutil
if __name__ == '__main__':
os.system('mkdir ~/Sources/out')
child_dirs = next(os.walk('~/Sources/'))[1]
num=1
for dir in child_dirs:
child_child_dirs = next(os.walk('~/Sources/{}'.format(dir)))[1]
for ch_dir in child_child_dirs:
if exists('~/Sources/{}/{}'.format(dir, ch_dir))==True:
shutil.move('~/Sources/{}/{}'.format(dir, ch_dir), '~/Sources/out/{}_image.fits'.format(num))
num+=1
else:
continue
Upvotes: 2
Views: 1774
Reputation: 11227
#!/usr/bin/env bash
new_dir="<target_folder>"
mkdir -p "$HOME/Sources/$new_dir/"
find "$HOME/Sources/" -type f -name 'image.fits' | while read -r fileName; do
mv "$fileName" "$HOME/Sources/$new_dir/$((n++))_${fileName##*/}"
done
Upvotes: 0
Reputation: 372
TARGET_FOLDER_NAME="<target_folder>"
TARGET_FILE_NAME="image.fits"
mkdir -p ~/Sources/$TARGET_FOLDER_NAME/
COUNT=1
find ~/Sources/ -type f -name $TARGET_FILE_NAME | while IFS= read -r -d '' file;
do
mv $file ~/Sources/$TARGET_FOLDER_NAME/$COUNT_$TARGET_FILE_NAME
COUNT=$((COUNT+1))
done
Upvotes: 1
Reputation: 10123
This two-line solution, which doesn't require any programming, is not exactly what you want, but should be close enough, assuming you have cp
from GNU coreutils, which is highly probable since the question is tagged with ubuntu-18.04.
shopt -s globstar
cp --backup=numbered Sources/**/image.fits target_folder/
Upvotes: 0
Reputation: 23794
It is supper easy
save your file in an array
mapfile -t files < <(find a b c d e -type f -name \*.txt)
# dry-run
COUNTER=0
for file in ${files[*]}; do ((++COUNTER)); echo $file dist/${COUNTER}-${file##*/}; done
output:
a/file.txt dist/1-file.txt
b/file.txt dist/2-file.txt
c/file.txt dist/3-file.txt
d/file.txt dist/4-file.txt
e/file.txt dist/5-file.txt
# safe run
# cp not mv
COUNTER=0
for file in ${files[*]}; do ((++COUNTER)); cp $file dist/${COUNTER}-${file##*/}; done
Delete your files after checking your destination directory
Or one line:
COUNTER=0; for file in {a,b,c,d,e}/*; do ((++COUNTER)); echo $file dist/${COUNTER}-${file##*/}; done
Replace echo
with cp
or mv
Upvotes: 0
Reputation: 622
This should do the magic:
import os
import shutil
if __name__ == '__main__':
child_dirs = next(os.walk('.'))[1]
os.mkdir('out')
num = 1
for dir in child_dirs:
shutil.copy2('{}/image.fits'.format(dir), 'out/{}_image.fits'.format(num))
num+=1
It does the following:
out
.Note: the script should be ran on the parent folder.
Upvotes: 2