2

How may I copy multiple files in multiple folders into one folder and change their names according to what directory they are copied from?

Initial directory hierarchy:

folder1/
    file1.gz
    filexyz.gz

folder2/
    file1.gz
    filexyz.gz

folder3/
    file1.gz
    filexyz.gz

Result:

folder1_file1.gz
folder2_file1.gz
folder3_file1.gz
folder1_filexyz.gz
folder2_filexyz.gz
folder3_filexyz.gz
1

4 Answers 4

1

Using a simple shell loop, assuming the files should be copied to the directory given by the value $destdir:

for pathname in */*.gz; do
    cp -i -- "$pathname" "$destdir/$( dirname -- "$pathname" )_$( basename -- "$pathname" )"
done
5
  • Also is it possible to keep the modified files in the same parent folders? Oct 4, 2019 at 22:21
  • @user1703276 Modified files? There is no modification to the files being done here.
    – Kusalananda
    Oct 4, 2019 at 22:26
  • sorry I meant renamed files like all folder1_* in folder1. Oct 4, 2019 at 22:27
  • @user1703276 I'm still not entirely sure I understand. Are you referring to my last sentence in the answer? I'm just having second thought about that particular sentence now and I think it ought to be fine with `$destdir" being any existing directory, even if it's a subdirectory in the current directory.
    – Kusalananda
    Oct 4, 2019 at 22:29
  • yes I was referring to your last comment. Yes, the initial directory should be the destination directory. Thank you. Oct 4, 2019 at 22:35
0

Something like this?

#!/bin/bash -ex
DESTDIR="PATH/TO/FINAL/DESTINATION/DIRECTORY"
for DIRS in /PATH/TO/YOUR/DIRECTORIES/*/;
do
    for FLES in $DIRS*.gz;
    do
        cp $FLES $DESTDIR/$(echo $(basename $DIRS)"_"$(basename $FLES))
    done
done

Edit: I've bothered to add no explanations to the code because the OP hasn't bothered to show that they've attempted to solve the problem themselves (if at all). But assistance should be rendered all the same, hence my post.

1
  • Note that $( echo $( ... ) ) is an anti-pattern that could be replaced by $( ... ) (unless you want the result of $( ... ) to undergo the special processing of backslashes that some implementations of echo performs).
    – Kusalananda
    Oct 1, 2019 at 7:57
0

Try this,

  find folder[1-3] -type f -name '*.gz' | while read -r FILE; do cp "$FILE" "${FILE//\//_}"; done
  • folder[1-3] source location.
  • -type f search only for files.
  • -name '*.gz' filename suffix with .gz.
  • ${FILE//\//_} replace '/' with underscore.
0

With prename/rename (aka Larry Wall's Perl-rename)(rename on Debian/Ubuntu, prename on RHEL/CentOS, IIRC):

In the parent of folder1, folder2, folder3:

rename -n s:/:_: */*

-n is the "dry run" parameter, replace by "-v" or remove if the renaming looks good.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.