1

Я хотел бы использовать команду find в for . Итак, я сделал это:

for logs in `find $BACKUP_FOLDER -exec ls -la {} \; | awk '{ if ( $8==2011) printf $0"\n" }'`; do
// some command here
done;

Но, похоже, это не работает, поэтому, если я попытаюсь выяснить, как интерпретируется команда, я добавлю эту строку в свой скрипт:

echo "$BACKUP_FOLDER -exec ls -la {} \; | awk { if ( '$8'==2011) printf $0"\n" }";

И $8 кажется пустым и \n пустым. Это то, что напечатано в терминале

/company-logs/engine -exec ls -la {} \; | awk { if ( ''==2011) printf /company/scripts/server/backup/sync_backup.shn }

Как я могу это исправить ?

1 ответ1

3

Ваш вопрос

echo "$BACKUP_FOLDER -exec ls -la {} \; | awk { if ( '$8'==2011) printf $0"\n" }";

не будет отображать ничего полезного по двум причинам:

  • Чтобы увидеть команду так, как она будет выполнена оболочкой, вы должны экранировать специальные символы $ и " с обратной косой чертой.

  • $8 - это только восьмой аргумент командной строки для bash. Чтобы увидеть, чем awk заменит его, вместо этого выполните эту команду:

    find $BACKUP_FOLDER -exec ls -la {} \; | awk '{ if ( $8==2011) printf $0"\n" }'
    

Ваш подход

Ваш цикл for не работает, так как printf $0 печатает всю строку из ls -l (содержит права, владельцев, дату и время).

Чтобы это исправить, вы должны удалить все, кроме имени файла, используя, например, сам awk или cut:

for logs in `find "$BACKUP_FOLDER" -exec ls -la {} \; | awk '{ if ( $8==2011) print $0 }' | cut -c 43-`; do ... done

Это создаст проблемы, если в именах файлов есть пробелы. Установка внутреннего разделителя файлов только на новую строку (IFS=$'\n' в bash) должна позаботиться о пробелах.

Твоя проблема

Ваш подход не очень переносим, поскольку другая версия ls или другая локаль могут изменить поля.

Для обработки всех файлов с 2011 года вместо вашего подхода я бы использовал

for logs in $(find "$BACKUP_FOLDER" -exec bash -c '[[ "$(stat -c %y "$0")" =~ ^2011 ]]' {} \; -print); do ... done

или, если возможно,

find "$BACKUP_FOLDER" -exec bash -c '[[ "$(stat -c %y "$0")" =~ ^2011 ]]' {} \; -exec ... \;

Опять же, изменение IFS должно позаботиться о пробелах, но второй подход будет более надежным.

find заменяет {} текущим обработанным файлом и передает его в качестве аргумента bash, который может получить к нему доступ как $0 .

stat -c %y "$0" показывает время модификации $0 и [[ "$(...)" =~ ^2011 ]] проверяет, начинается ли оно с 2011 .

Если это так, bash -c '...' возвращает true, а -print печатает имя файла или -exec выполняет команду.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .