2

I have some files in a folder, which are named ***_code_c**** (where * represents any letter or number). I have another folder that have many files, folders and subfolders inside it. What I want to do is to look for and copy to another location any files that matches the names of these files like ***_code_c**** but with only two letters different like this ***_mode_m**** and ***_kode_c**** and any of the files that matches this criteria will be copied to a specific folders where the ones having the mode instead of code will be placed in a folder and the ones having the kode instead of code will be placed in another folder. If anyone could please advise how this can be done. Thanks

Example to clarify what needs to be done:

FolderA has some files in it lets say ABC_code_c001, CDE_code_c002, FGH_code_c003 ...

Another FolderB has many files, folders and subfolders inside it.

for every file in FolderA there is a corresponding two files in FolderB which are named exactly the same except for the middle part. For example the corresponding two files of ABC_code_c001 are ABC_kode_c001 and ABC_mode_m001, while the corresponding files of FGH_code_c003 will be FGH_kode_c003 and FGH_mode_m003 and so on

So, what I want to do is to take every file in FolderA and search for the two corresponding files in FolderB then copy each of these two files in two other folders lets say FolderC and FolderD(one in each).

Note that the names I'm using is not the exact names I listed in the example, but it has the same idea where the difference between its name and the two other names will be one letter in the middle from c to k and m.

12
  • I need a lot more coffee before I could tell you how, but I think you can do it with the "find" command. Actually, you can do almost anything with find command. It has the ability to do regular expressions, and to execute any command with what it finds. Sep 28, 2014 at 19:24
  • I wish I could make you couple of coffee cups :) . My problem is that I'm just an early beginner in Ubuntu this is why I'm here asking experts to assist me :) so I'd really appreciate if you could please assist me.
    – Tak
    Sep 28, 2014 at 19:26
  • Sorry, but for me, it would be more work than I'm willing to do. All I can advise is to search for find command examples, and regex example (you may not need that, though). If it's too much for you to follow, perhaps someone who knows regex or has more experience in shell scripting will accept the challenge. Sep 28, 2014 at 19:46
  • This is the level of complexity where I would consider moving away from shell scripting to a scripting language such as Python. Would you be Ok with that? I have to confess, though, that I haven't completely understood your specification yet. Could you inlude a minimal but concrete example of the files in the seperate directories? Sep 28, 2014 at 20:13
  • @MarcusRickert I don't mind for sure :) okay, could you tell me exactly what needs more specification to clarify more?
    – Tak
    Sep 28, 2014 at 20:15

3 Answers 3

1

Let's say you're in your $HOME, and you have four directories -- folderA and folderB, as in your question; folderK, where you want to move the 'kode' files to; and folderM, where you want to move your 'mode' folders to. The following should accomplish that:

shopt -s globstar
cd /path/to/folderA
for f in *_code_c*; do
  mv /path/to/folderB/**/"${f/code/kode}" /path/to/folderK
  mv /path/to/folderB/**/"${f/code_c/mode_m}" /path/to/folderM
done

Obviously test it out on some dummy data first.

4
  • I'll come back and explain it all tomorrow (it's a wee bit past my bed time right now). To be getting on with, it might be worth your while reading this, simce I think that's the most unusual thing I've used here.
    – evilsoup
    Sep 28, 2014 at 21:13
  • I just have a question regarding the *_code_c* will this put in consideration the letters before _code_c and letters after in the search for the corresponding ones?
    – Tak
    Sep 28, 2014 at 21:27
  • It's what's knpwm as a glob: basically * means 'any number of any characters'. *_code_c* will expand into a list of all the files that match the pattern 'any number of any characters, followed by "_code_c", followed by any number of any characters'. The 'for f in' bit (called a 'for loop') loops over that list and performs all the actions between 'do' and 'done' for each file in the list, individually. I hope that all makes sense ;)
    – evilsoup
    Sep 28, 2014 at 21:36
  • Thanks :) but I want it to take in consideration what's before and after _code_c because if it didn't then there will be thousands of file that match the _code_c criteria, does your solution will handle this?
    – Tak
    Sep 28, 2014 at 21:39
1

Create a simple file copyFile.sh as follow:

#!/bin/bash
kodeFile=$(basename $1 | sed -e 's/_code_c/_kode_c/')
modeFile=$(basename $1 | sed -e 's/_code_c/_mode_m/')
find FolderB -name "$modeFile" -exec cp {} FolderC/$modeFile \;
find FolderB -name "$kodeFile" -exec cp {} folderD/$kodeFile \;

save it, for example in /home/yourUser/bin.

Change permission to copyFile.sh:

chmod +x /home/yourUser/bin/copyFile.sh

Open you /home/yourUser/.bashrc file and add at the end this line:

PATH=$PATH:/home/yourUser/bin

save it and reload it:

source .bashrc

Now you have a new utility that search file and copy them.

Try this:

find FolderA -name "*_code_c*" -exec copyFile.sh {} \;

Tested on lubuntu 12.04

1

I believe this is exactly doing what you describe.

The script below seems a bit verbose, but a great part of it is taken by the necessary information the user has to give in this somewhat complicated construction.

How to use

As always, copy the script below, enter the appropriate paths, in this case quite a few, the appropriate identifying strings, and save it as reorg.py.

Run it by the command:

python3 /path/to/reorg.py

The script

#!/usr/bin/env python3

import os
import shutil

# --------------------------------------------------------
# existing files directories
original_dir = "/path/to/original_files"
equals_dir = "/path/to/files_with_name_variants"
# original identifying string
id_string = "code" 
# variants + their desired destination
var_1 = "node"; vardir_1 = "/path/to/directory/where_first_variants_shouldbestored"
var_2 = "kode"; vardir_2 = "/path/to/directory/where_second_variants_shouldbestored"

# ---------------------------------------------------------

origs = []

for root, dirs, files in os.walk(original_dir):
    for name in files:
        if id_string in name:
            origs.append(name.replace(id_string, ""))

for root, dirs, files in os.walk(equals_dir):
    for name in files:
        if var_1 in name:
            if name.replace(var_1, "") in origs:
                shutil.copyfile(root+"/"+name, vardir_1+"/"+name)
        if var_2 in name:
            if name.replace(var_2, "") in origs:
                shutil.copyfile(root+"/"+name, vardir_2+"/"+name)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .