Script to backup multiple files and amend their filenames

Hi,

I'm trying to write a command that backs up certain files into my current directory and adds a prefix to the backed up file name. I realise this can be done in a script by specifying each individual file but would like to know if it can be done on one line and made an alias.

I have the following files
AMQERR01.LOG
AMQERR02.LOG
AMQERR03.LOG

and I want to create backups called
$QM-AMQERR01.LOG
$QM-AMQERR02.LOG
$QM-AMQERR03.LOG

I've been using this command
find /var/mqm/qmgrs/$QM/errors -name "AMQERR*" -exec cp {} $QM-* \;
but the cp command creates one file called, e.g. QMNAME-*

I also tried
find /var/mqm/qmgrs/$QM/errors -name "AMQERR*" -exec cp {} $QM-{} \;
but the file was renamed QMNAME-{}

Is this possible?

Regards

Gareth

Two ways:

  1. Backup all files in a single directory:
for QM in (specify list of queue managers here); do
   cd /var/mqm/qmgrs/$QM/errors
   for file in AMQERR*; do
      cp -p $file /central_dir_path/$QM-$file;
   done
done
  1. Backup files in their own directory:
for QM in (specify list of queue managers here); do
   cd /var/mqm/qmgrs/$QM/errors
   for file in AMQERR*; do
      cp -p $file $QM-$file
   done
done

Note: not tested

Yup. Try this:

alias doit='find . -name "AMQERR*" -print | sed -e "s#\.\/##" | xargs -l -i cp {} \$QM-{}'

...Note that this code will descend into any subdirectories, which may not be what you want. Substitute a directory for dot, if you want (and maybe exclude the sed command).
-mschwage

Thanks for both these suggestions. I've tried this one liner and am hitting a problem. I don't think the sed command is working as I was getting an error. I've amended the code as follows to try and debug it:

alias doit='find /var/mqm/qmgrs/$QM/errors -name "AMQERR*" -print | sed -e "s#\.\/##" | xargs -l -i echo $QM-{}'

The result is as follows:

STPFAUQA-/var/mqm/qmgrs/STPFAUQA/errors/AMQERR03.LOG
STPFAUQA-/var/mqm/qmgrs/STPFAUQA/errors/AMQERR02.LOG
STPFAUQA-/var/mqm/qmgrs/STPFAUQA/errors/AMQERR01.LOG

The output from the find is:
/var/mqm/qmgrs/STPFAUQA/errors/AMQERR03.LOG
/var/mqm/qmgrs/STPFAUQA/errors/AMQERR02.LOG
/var/mqm/qmgrs/STPFAUQA/errors/AMQERR01.LOG

What sed expressions should I use to change this to just the filename? Or alternatively is there an ls command which can just display the filename negating the need for the sed?

Regards

Gareth

Ooo, that's a tough trick. You want to modify the value in {}, which I don't think can be done. Probably you should change the alias:

alias doit='(cd /var/mqm/qmgrs/$QM/errors; find . -name ......)'

...surround your commands with ()'s to run it in a subshell, then do a cd inside it. That will do the find in the new directory without putting you in the new directory. Make sure the ()'s are inside the single-quotes.

I prefer to use the . because an * can potentially fill the input buffer and create an invalid shell command. (Think about it for a second... the * matches all files in the current directory... if there are a lot of files, there will be a lot of matches. Whereas the find command's job is not to do shell metacharacter matching, it's to print out files that match your characteristics, line by line. This makes the dot safer to use with find.).

Thanks for this tip. It almost worked but not quite as the output of the find was as below and the ./ caused problems.

./AMQERR03.LOG
./AMQERR02.LOG
./AMQERR01.LOG

In the end I used the original version and used cut to extract the file name. The command is pretty long but it works.

alias doit='find /var/mqm/qmgrs/$QM/errors -name "AMQERR*" -print |cut -d/ -f7| xargs -l -i cp /var/mqm/qmgrs/$QM/errors/{}
                 $HOME/backuplogs/$QM-$(date -u +%b)$(date -u +%d)-{}'