Shell – Traverse, copy & transform file names

filesrenameshell-script

My issue: I need to copy log files, all with identical names, but stored 1-deep in subdirectories, and change their names.

I'm copying from the a folder called Logfiles which contains a bunch of folders:

W3SVC114, W3SVC1507562355, W3SVC350179472, etc.

Each of these folders will contain a file named: u_ex[YYMMDD].log, where [YYMMDD] is a datestamp.

I need all of these logfiles in one folder. Since all names are identical I would like to add the directory name to the resulting file name, for example:

W3SVC1507562355/u_ex150407.log becomes W3SVC1507562355_u_ex150407.log

How do I make all of these happen? I'm a bit out of my depth here… :-/

Best Answer

Zsh comes with a function called zmv that makes it easy to move or copy files and apply pattern-based transformations on the name. Put this in your .zshrc (or run it on the command line):

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

Then your copy-with-renaming can be done with any of the following equivalent commands:

zcp 'Logfiles/(*)/(*.log)' 'destination_directory/${1}_$2'
zcp -w 'Logfiles/*/*.log' 'destination_directory/${1}_${2}.log'
zcp -W 'Logfiles/*/*.log' 'destination_directory/*_*.log'

If you don't want to install zsh, you can do the same thing with a loop in any shell:

cd Logfiles
for x in */*.log; do
  cp -- "$x" "destination_directory/${x%/*}_${x##*/}"
done
Related Question