Home > Mobile >  Copying files of the same name from multiple directories into one directory
Copying files of the same name from multiple directories into one directory

Time:07-27

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.

CodePudding user response:

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:

  1. Gets the current child folders.
  2. Creates a new folder called out.
  3. Loops over the folder child folders and copies the files to the new folders.

Note: the script should be ran on the parent folder.

CodePudding user response:

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

CodePudding user response:

It is supper easy

first

save your file in an array

mapfile -t files < <(find a b c d e -type f -name \*.txt)

Second

# 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

thrid

# safe run
# cp not mv
COUNTER=0
for file in ${files[*]}; do ((  COUNTER)); cp $file dist/${COUNTER}-${file##*/}; done

last

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

CodePudding user response:

#!/usr/bin/env bash

new_dir="<target_folder>"

find "$HOME/Sources/" -type f -name 'image.fits' | while read -r fileName; do
    mkdir -p "$HOME/Sources/$new_dir/"
    mv "$fileName" "$HOME/Sources/$new_dir/$((n  ))_${fileName##*/}"
done

CodePudding user response:

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/
  • Related