Помощь в создании скрипта

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

if [ "$a" = "y" ] || [ "$a" = "Y" ]; then
    if printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
        # both conditions met: do stuff
    fi
fi

(обратите внимание, что ==являетсяbash-измом)

Их объединение (делает его менее читабельным ИМХО):

if [ "$a" = "y" ] || [ "$a" = "Y" ] && printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
    # both conditions met: do stuff
fi

Для базовых регулярных выражений вы можете использоватьexpr(см. комментарий Стефана Шазела ниже, хотя):

if [ "$a" = "y" ] || [ "$a" = "Y" ] && expr "$b" : 'SOME_REGEX' >/dev/null; then
    # both conditions met: do stuff
fi

Оболочка /bin/shобычно не имеет [[... =~... ]]расширенного сопоставления регулярных выражений.


Что касается вашего примечания в конце :Регулярные выражения предназначены для сопоставления отдельных строк текста . Если вы обрабатываете имена файлов как текст, вы автоматически исключаете любое имя файла, которое не является одной строкой текста, например, имена файлов, содержащие символы новой строки. Если вам нужно применить сопоставление регулярных выражений к именам файлов, делайте это осторожно с именами, хранящимися в массиве($@в /bin/sh), или используйте реализацию find, которая поддерживает предикат -regex.

Шаблоны подстановки имен файлов предназначены для сопоставления имен файлов.

1
17.07.2020, 11:52
2 ответа

Я изменил то, что вы предоставили, чтобы добавить цикл for, в котором вы можете указать различные префиксы журнала. Это предполагает, что вы вызываете этот скрипт каждые 15 минут из планировщика заданий, такого как cron или autosys, если нет, то его можно обернуть в цикл while true с 15-минутным спящим режимом.

TIMESTAMP=`date "+%Y.%m.%d-%H.%M"`
LOGS="AppA AppB"
# to pull log prefixes from a file replace with the next line
#LOGS="$(cat prefixes.txt)"
LOGSUFFIX=".log.4"
APPLOGS_DIR="/logs"
BACKUP_DIR="/backupDIR"

for LOG in ${LOGS}
do
    if [ -f "${APPLOGS_DIR}/${LOG}${LOGSUFFIX}" ]
    then
        mv "${APPLOGS_DIR}/${LOG}${LOGSUFFIX}" "${BACKUP_DIR}/${LOG}_${TIMESTAMP}"
        gzip "${BACKUP_DIR}/${LOG}_${TIMESTAMP}"
    else
        echo "No ${LOG}${LOGSUFFIX} file to be backed up"
    fi
done
0
18.03.2021, 23:19

вы можете использовать цикл forи использовать манипуляции со строками для создания имени выходного файла ${var%.*}на основе имени входного файла

TIMESTAMP=$(date "+%Y.%m.%d-%H.%M")
APPLOGS_DIR="./logs"
BACKUP_DIR="./backupDIR"

# canonicalize relative paths
APPLOGS_DIR=$(realpath "$APPLOGS_DIR")
BACKUP_DIR=$(realpath "$BACKUP_DIR")

# delete this line - just for demo
echo "AppA.log.4\nAppB.log.4" >>./index.txt

# read file names from list
LOGS=$(sort./index.txt | uniq) || exit 127

cd "$APPLOGS_DIR" || exit 127

for log in $LOGS
  do
    if [ -f "$log" ]
      then
        mv -f $log "$BACKUP_DIR"
        cd "$BACKUP_DIR" || exit 127
        mv $log ${log%.*}_${TIMESTAMP}
        gzip ${log%.*}_${TIMESTAMP}
        cd "$APPLOGS_DIR"
      else
        echo "No log file to be backed up"
    fi
done

Однако просто архивировать и удалить файл можно и безcd

while IFS='' read -r log || [ "$log" ]
  do
    [ -f "$APPLOGS_DIR/$log" ] && \
    gzip -nc "$APPLOGS_DIR/$log" > "$BACKUP_DIR/${log%.*}_${TIMESTAMP}.${log##*.}.gz" && \
    rm "$APPLOGS_DIR/$log" || \
    echo "No '$log' file to be backed up"
done <<< $(sort./index.txt | uniq)

или как один -вкладыш (, когда имена выходных файлов не имеют значения и имена файлов не содержат пробелов )используйте флаг -Sдля суффикса и обработайте index.txt прямо из gzipбез петли

cd "$APPLOGS_DIR" && \
gzip -S.${TIMESTAMP}.gz $(cat $OLDPWD/index.txt) && \
mv -f *.${TIMESTAMP}.gz "$BACKUP_DIR"
2
18.03.2021, 23:19

Теги

Похожие вопросы