Skip to main content
added explanations
Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118

Using find and shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion as following.

find . -type f -name "F3.bam" -execdir sh -c '
    trgt="${PWD%*PWD%/*/*}"; echo cp -v "$1" "${trgt}/${trgt##*/}_${1#./}" ' _ '{}' \;

Explanations::

We are looking for the files only matching F3.bam and with -execdir here, find is changing the current directory to the directory where file F3.bam found then execute the sh -c ' ... ' within that directory itself.

With trgt="${PWD%/*/*}" "cut-up-to-first-suffix": We are getting ride of the filename itself and two level of its sub-directories in /samples/mydata1/RUN1/ID_date**/PCR2/TIME1** (bold part that matches /*/* suffix will remove) and assign to variable trgt. So trgt is now set to /samples/mydata1/RUN1/ID_date for first file.

The "$1" is relative filepath ./filename to the current $PWD.

In ${trgt##*/}_ "cut-up-to-last-prefix": We used trgt variable value to get the sub-directory name which should pre-pend to the filename, So this will return only ID_date, ID2_date4 or IDxxx_datexxx, etc (removing everything until last slash / seen) and add a underscore _.

This ${1#./} removes point-slash ./ from the relative ./filepath.

Using find and shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion as following.

find . -type f -name "F3.bam" -execdir sh -c '
    trgt="${PWD%*/*/*}"; echo cp -v "$1" "${trgt}/${trgt##*/}_${1#./}" ' _ '{}' \;

Using find and shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion as following.

find . -type f -name "F3.bam" -execdir sh -c '
    trgt="${PWD%/*/*}"; echo cp -v "$1" "${trgt}/${trgt##*/}_${1#./}" ' _ '{}' \;

Explanations::

We are looking for the files only matching F3.bam and with -execdir here, find is changing the current directory to the directory where file F3.bam found then execute the sh -c ' ... ' within that directory itself.

With trgt="${PWD%/*/*}" "cut-up-to-first-suffix": We are getting ride of the filename itself and two level of its sub-directories in /samples/mydata1/RUN1/ID_date**/PCR2/TIME1** (bold part that matches /*/* suffix will remove) and assign to variable trgt. So trgt is now set to /samples/mydata1/RUN1/ID_date for first file.

The "$1" is relative filepath ./filename to the current $PWD.

In ${trgt##*/}_ "cut-up-to-last-prefix": We used trgt variable value to get the sub-directory name which should pre-pend to the filename, So this will return only ID_date, ID2_date4 or IDxxx_datexxx, etc (removing everything until last slash / seen) and add a underscore _.

This ${1#./} removes point-slash ./ from the relative ./filepath.

Source Link
αғsнιη
  • 41.9k
  • 17
  • 75
  • 118

Using find and shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion as following.

find . -type f -name "F3.bam" -execdir sh -c '
    trgt="${PWD%*/*/*}"; echo cp -v "$1" "${trgt}/${trgt##*/}_${1#./}" ' _ '{}' \;