Copy specific file (different but same name) as folder name

I have to copy a particular file present in a main folder having part of the file-name present in many sub-folders to a new destination preserving the name of the source "part of the main folder" and previous file-name of the output file:

Example:

From /005_0/1000/005.xxx -> /copy/005_1000.xxx
From /005_0/1001/005.xxx -> /copy/005_1001.xxx
From /005_0/1002/005.xxx -> /copy/005_1002.xxx
From /005_0/1003/005.xxx -> /copy/005_1003.xxx
From /005_1/1004/005.xxx -> /copy/005_1004.xxx
From /005_1/1005/005.xxx -> /copy/005_1005.xxx
From /006_0/1006/006.xxx -> /copy/006_1006.xxx
From /006_1/1007/006.xxx -> /copy/006_1007.xxx
From /006_1/1008/006.xxx -> /copy/006_1008.xxx
...

Can someone give me the command to type under RedHat (csh and bash) please? - Many thanks :smiley:

Hello wappor,

Could you please try following and let me know if this helps.

cat test19.ksh
SOURCE=$1
DESTINATION=$2
awk  -vsource=`echo $SOURCE` -vdestination=`echo $DESTINATION` --re-interval 'BEGIN{match(source,/\/[0-9]{4}\//);A=substr(source,RSTART+1,RLENGTH-2);match(source,/\/[0-9]+\./);B=substr(source,RSTART+1,RLENGTH-2);match(source,/\..*/);C=substr(source,RSTART,RLENGTH);match(destination,/\/[a-zA-Z]+\//);D=substr(destination,RSTART,RLENGTH);print "cp " source " " D B"_" A C}'

We can run it as follows by providing 2 arguments first as source file path and second is destination file path as follows.

./test19.ksh /005_0/1000/005.xxx  /copy/
cp /005_0/1000/005.xxx /copy/005_1000.xxx

If you are happy with results above you can run following script then which will copy the files as follows.

cat test19.ksh
SOURCE=$1
DESTINATION=$2
awk  -vsource=`echo $SOURCE` -vdestination=`echo $DESTINATION` --re-interval 'BEGIN{match(source,/\/[0-9]{4}\//);A=substr(source,RSTART+1,RLENGTH-2);match(source,/\/[0-9]+\./);B=substr(source,RSTART+1,RLENGTH-2);match(source,/\..*/);C=substr(source,RSTART,RLENGTH);match(destination,/\/[a-zA-Z]+\//);D=substr(destination,RSTART,RLENGTH);print "cp " source " " D B"_" A C}' | sh

NOTE: Also if you are happy with results then you can read all the files which you want to copy to a destination directory and pass it to script then.

Thanks,
R. Singh

Thanks for your help but unfortunately I have the following with my awk:

awk: not an option : --re-interval

:confused:

Hello wappor,

Kindly use code tags for commands in your posts as per forum rules. Could you please try following and let me know.

cat test19.ksh
SOURCE=$1
DESTINATION=$2
awk  -vsource=`echo $SOURCE` -vdestination=`echo $DESTINATION` 'BEGIN{match(source,/\/[0-9]+\//);A=substr(source,RSTART+1,RLENGTH-2);match(source,/\/[0-9]+\./);B=substr(source,RSTART+1,RLENGTH-2);match(source,/\..*/);C=substr(source,RSTART,RLENGTH);match(destination,/\/[a-zA-Z]+\//);D=substr(destination,RSTART,RLENGTH);print "cp " source " " D B"_" A C}'

After running the script we will get following results.

./test19.ksh /005_0/1000/005.xxx  /copy/
cp /005_0/1000/005.xxx /copy/005_1000.xxx

Thanks,
R. Singh

Thanks for that again and Sorry about the code tags - I just registered and as everyone, I don't read the terms before clicking "I agree" :slight_smile:

The 'cp ' doesn't appear in the command and could you please tell me more about RSTART and RLENGTH please... What does it take when coded?

Many thanks

Hello wappor,

Could you please let me know what error you are getting while executing it?
Also RSTART and RLENGTH meaning is as follows.

Thanks,
R. Singh

If I'm right, you want to take the second directory in the path and use that as part of the file name in the common target directory.

If you use find to get the list of files and assuming that you can limit the search in some way, (e.g. define source_dirs as a space separated list of directories to search, define name_pattern as an expression, e.g. "*.xxx" ) you can do the following (in ksh and perhaps bash):-

for FQfile in $(find $source_dirs -type f -name "$name_pattern")
do
   dirsplit="${FQfile#/*/}"               # Remove first directory from fully qualified file name
   second_dir="${dirsplit%%/*}            # Extract just the next directory from the above
   file_name="${FQfile##*/}"              # Get just file file name part
   f1="${file_name%%.*}"                  # Get the first part of the file name (split at the full-stop)
   f2="${file_name##*.}"                  # Get the last part of the file name (split at the full-stop)
   print "cp -p $FQfile /copy/${f1}_${second_dir}.${f2}"
done

This may run marginally slower than the awk, but hopefully it shows you what is happening and the logic behind it. I'm using "variable substitution" to slice up the fully qualified file name to get the useful parts and then build the output line at the end.

You haven't said how you generate the list of files, so I've gone with a find command. If you have a file with them all listed, you could just change the loop to be:-

while read FQfile
do
   dirsplit=.......
   :
   :
done < input_file

I hope that this helps and that you can follow the logic.

Robin

Try also

ls /00* |
while read FN  REST
        do T1=${FN#${FN%/*/*}/}
           T2=${FN##*/}
           echo cp $FN /copy/${T2%.*}_${T1%/*}.${T2#*.}
        done

remove echo when happy...