Изменить суффикс (ы) имени файла (используя sed?) - PullRequest
4 голосов
/ 11 сентября 2010

Я бы хотел изменить суффикс имени файла из файлов (используя bash-скрипт), но иногда встречаются файлы с одним периодом, а некоторые с двумя.

Теперь я используюthis:

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

Где 'new_file' - это новое имя файла, 'file' - оригинальное имя файла, '$ {suf}' суффикс файла и $ {num} новый номер.

Так что some.log должно стать some.log.1 и some.log.1 должно стать some.log.2 .С моим кодом some.log становится some.log.1 , но some.log.1 остается some.log.1 .

Надеюсь, я достаточно ясно.Я ценю любой совет (даже не используя sed).

Обновление:

@ paxdiablo .Я думаю, что-то пошло не так, тестируя.

Теперь я использую этот кусок кода в качестве теста;

#!/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

Теперь все работает нормально.Извините за путаницу.

Ответы [ 2 ]

5 голосов
/ 11 сентября 2010

Если вы хотите пролистать файлы журналов, и в зависимости от того, насколько сложным вам нужно получить, я уже использовал следующий сегмент:

#!/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

Это автоматически свернет файлы журналов вверхдо версии 9, хотя вы можете просто изменить цикл suff for, чтобы разрешить больше.

После добавления DEBUG новые файлы создаются автоматически для тестирования, следующая стенограмма показывает это в действии:

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

Хорошая особенность этого сценария в том, что он легко конфигурируется для обработки большого количества истории (путем изменения бита {8..1}), обрабатывает имена с пробелами и относительно надежно обрабатывает пропуски, если файлы журнала идутотсутствует.

2 голосов
/ 11 сентября 2010

Чтобы вращать журналы, вам действительно нужно использовать logrotate .

Если вы не можете полагаться на доступность logrotate, вот способ сделать это внутри оболочки.Для простоты я предполагаю, что ничто другое (включая другой экземпляр вашего скрипта) не будет пытаться переименовать файлы журналов во время работы вашего скрипта.

Самый простой подход - это рекурсивное переименование журнала N + 1перед фактическим переименованием журнала N в N + 1.Оболочка может выполнить всю необходимую арифметику, вам не нужно sed здесь.Обратите внимание, что хотя в POSIX-оболочке возможны рекурсивные функции, локальных переменных, кроме позиционных параметров, не существует (многие оболочки предлагают локальные переменные в качестве расширения).что echo ${file} плохо по двум причинам: наиболее важно, если ${file} содержит какие-либо специальные символы, такие как пробел, оболочка будет их интерпретировать;также, с некоторыми оболочками, echo сам будет интерпретировать обратную косую черту и, возможно, ведущий -.Поэтому вы всегда должны писать printf %s "$file".

...