Search code examples
shellsedfilenamesrename

Change file name suffix(es) (using sed ?)


I'd like to change the file name suffix from files (using a bash script), but sometimes there are files with one period and some with two.

Now I use this:

new_file=`echo ${file} | sed 's/\(.*\.log.*\)'${suf}'/\1.'${num}'/'`

Where 'new_file' is the new file name, 'file' the original file name, '${suf}' the file's suffix and ${num} a new number.

So some.log must become some.log.1 and some.log.1 must become some.log.2. With my code some.log becomes some.log.1, but some.log.1 remains some.log.1.

I hope I'm clear enough. I appreciate any advice (even not using sed).

Update:

@paxdiablo. Something went wrong testing I think.

Now I use this piece of code as test;

#!/usr/bin/bash

        shft() {
            for suff in {6..1} ; do
                if [[ -f "$1.${suff}" ]] ; then
                    ((nxt = suff + 1))
                    echo Moving "$1.${suff}" to "$1.${nxt}"
                    mv -f "$1.${suff}" "$1.${nxt}"
                fi
            done
            echo Moving "$1" to "$1.1"
            mv -f "$1" "$1.1"
        }

        clear

        folder=~/logs/*.log

        for i in {1..20}; do
            echo ${i}> ~/logs/some.log 

            for fspec in ${folder} ; do
                    shft "${fspec}"
            done
        done

Every thing works fine now. Sorry for the confusion.


Solution

  • If you're looking to roll over log files, and depending on how complex you need to get, I've used the following segment before:

    #!/usr/bin/bash
    # rollover.sh
    #   Rolls over log files in the current directory.
    #     *.log.8 -> *.log.9
    #     *.log.7 -> *.log.8
    #     : : :
    #     *.log.1 -> *.log.2
    #     *.log   -> *.log.1
    
    shft() {
        # Change this '8' to one less than your desired maximum rollover file.
        # Must be in reverse order for renames to work (n..1, not 1..n).
        for suff in {8..1} ; do
            if [[ -f "$1.${suff}" ]] ; then
                ((nxt = suff + 1))
                echo Moving "$1.${suff}" to "$1.${nxt}"
                mv -f "$1.${suff}" "$1.${nxt}"
            fi
        done
        echo Moving "$1" to "$1.1"
        mv -f "$1" "$1.1"
    }
    
    for fspec in *.log ; do
        shft "${fspec}"
        #date >"${fspec}" #DEBUG code
    done
    

    This will automatically roll over log files up to version 9 although you can just change the suff for loop to allow more.

    With that DEBUG added so new files are created automatically for testing, the following transcript shows it in action:

    pax> touch qq.log ; ./rollover.sh
    Moving "qq.log" to "qq.log.1"
    
    pax> touch "has spaces.log" ; ./rollover.sh
    Moving "has spaces.log" to "has spaces.log.1"
    Moving "qq.log.1" to "qq.log.2"
    Moving "qq.log" to "qq.log.1"
    
    pax> ll *log*
    -rw-r--r-- 1 pax None 30 2010-09-11 20:39 has spaces.log
    -rw-r--r-- 1 pax None  0 2010-09-11 20:39 has spaces.log.1
    -rw-r--r-- 1 pax None 30 2010-09-11 20:39 qq.log
    -rw-r--r-- 1 pax None 30 2010-09-11 20:38 qq.log.1
    -rw-r--r-- 1 pax None  0 2010-09-11 20:38 qq.log.2
    

    The good thing about this script is that it's easily configurable to handle a large amount of history (by changing the {8..1} bit), handles names with spaces, and handles gaps relatively robustly if log files go missing.