I have files in /root/test/access.log.1 to 999 and /root/test/error.log.1 to 999.

I would like to rename access.log.1 to access.log.2 and move to /var/log/archives/, and same way error.log.1 to error.log.2.

I tried something like below

NEWFILE=`ls -ltr |grep error |tail -2 | head -1 |awk '{print $9}'`
for i in `ls -ltr |grep error |tail -1`;
    mv "$i" /var/log/archives/"$NEWFILE"
  • That script is way more complicated than what you're asking, so please edit the question to clarify exactly what you need. – wjandrea Mar 22 '18 at 19:44
  • To clarify, this fits your description, but it's trivial: mv /root/test/access.log.1 /var/log/archives/access.log.2; mv /root/test/error.log.1 /var/log/archives/error.log.2 – wjandrea Mar 22 '18 at 19:46

Simple bash script:

for file in {access,error}.log.{999..1}; do
    echo "$file" "/path/to/dest/${file//[0-9]}$((${file//[a-z.]}+1))";
  • ${file//[0-9]}, this removes digits and keep alphabet only which will result error.log. or access.log. part.
  • ${file//[a-z.]}, this removes alphabet and dots only (I write a-z. because of your files name patterns), which will result numeric part; and
  • $((${file//[a-z.]}+1)) will increment one to the numeric part as produced by above.

This will rename files as below and move to /path/to/dest/:

access.log.999 --> /path/to/dest/access.log.1000
access.log.998 --> /path/to/dest/access.log.999
error.log.999 --> /path/to/dest/error.log.1000
error.log.998 --> /path/to/dest/error.log.999

Note that replace echo for dry-run with mv to have rename on files.

  • file moving as like below access.log.52 --> /path/access.log.5253 access.log.53 --> /path/access.log.5354 – Ravi Ankam Mar 22 '18 at 20:06
  • see my update.. – αғsнιη Mar 22 '18 at 20:39
#! /usr/bin/env bash

# exit on error
set -e

# increase the numbers of the old archives (mv -i avoids accidental overwrite)
for ((i=999; i >= 2; i--)); do
    for name in access error; do
        if [[ -e /var/log/archives/$name.log.$i ]]; then
            mv -i "/var/log/archives/$name.log.$i" "/var/log/archives/$name.log.$((i+1))"

# move current files to archives
for name in access error; do
    mv -i "/root/test/$name.log.1" "/var/log/archives/$name.log.2"

We could run something along the lines of

perl -E 'for (reverse 1..999){
            rename( "access.log.$_" , "access.log.".($_+1))}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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