2010-05-12 2 views
2

Каждый день приложение создает файл с именем file_YYYYMMDD.csv, где YYYYMMDD - дата изготовления. Но иногда генерация терпит неудачу, и файлы не создаются на пару дней.файлы, индексированные по дате производства

Мне бы хотелось, чтобы простой способ в сценарии bash или sh найти имя файла самого последнего файла, который был выпущен до заданной контрольной даты.

Типичное использование: найти последний сгенерированный файл, не считая выпущенных после 1 мая.

Спасибо за вашу помощь

+0

Вы спрашиваете, чтобы найти имя файла самого последнего имя файла как одно или как часть скрипта? – Casey

+0

Я хотел бы поместить его в переменную, чтобы потом использовать ее в скрипте. Я вижу много способов добиться этого, ни один из них не прост. – caas

ответ

0

Этот сценарий позволяет избежать:

  • Использование sed неоднократно в цикле
  • Parsing ls
  • Создание подоболочку в цикле while
  • Обработка файлов, которые не совпадают с именем file_*.csv образец

Вот сценарий:

#!/bin/bash 
while read -r file 
do 
    date=${file#*_} # strip off everything up to and including the underscore 
    date=${date%.*} # strip off the dot and everything after 
    if [[ $date < $1 ]] 
    then 
     break 
    fi 
done < <(find -name "file_*.csv" | sort -r) 

# do something with $file, such as: 
echo "$file" 

Edit:

С Bash> = 3.2, вы можете сделать это, используя регулярное выражение:

#!/bin/bash 
regex='file_([[:digit:]]+).csv' 
while read -r file 
do 
    [[ $file =~ $regex ]] 
    date=${BASH_REMATCH[1]} 
    if [[ $date < $1 ]] 
    then 
     break 
    fi 
done < <(find -name "file_*.csv" | sort -r) 

# do something with $file, such as: 
echo "$file" 
+0

Спасибо, тоже очень приятно. Я предпочитаю решение, которое использует sed, поскольку оно предлагает больше возможностей для управления файлами. Пример: иногда файлы, называемые 'file_YYYYMMDD_test.csv', появляются в каталоге. Я попытаюсь смешать оба сценария, чтобы добавить другие улучшения, которые вы предлагаете. Спасибо! – caas

+0

@caas: см. Мое редактирование для версии, которая использует регулярные выражения Bash и похожа на версию 'sed'. –

0

Попробуйте это:

#!/bin/bash 

ls -r | while read fn; do 
    date=`echo $fn | sed -e 's/^file_\([0-9]*\)\.csv$/\1/'` || continue 
    if [ $date -lt $1 ]; then 
     echo $fn 
     exit 
    fi 
done 

Просто позвоните этот скрипт с базовой датой вы хотите сравнить с. Замените -lt на -le, если вы хотите включить контрольную дату.

Редактировать: Альтернативное решение, без подачи эхо-переменной. Обратите внимание, что я не тестировал его, но он тоже должен работать.

#!/bin/bash 

ls -r | sed -e 's/^file_\([0-9]*\)\.csv$/\1/' | while read date; do 
    if [ $date -lt $1 ]; then 
     echo "file_${date}.csv" 
     exit 
    fi 
done 
+0

Уход! Можно ли сделать это без трубки «echo $ fn» для sed (т. Е. Положить $ fn непосредственно в качестве аргумента sed)? – caas

+0

Поскольку sed работает на входе, вы должны его эхо. Конечно, вы могли бы использовать «здесь документ», но это намного сложнее.Вы можете также передать вывод ls через sed перед чтением строки. Но в этом случае вам придется самим воссоздать имя файла, повторив его. – petersohn

+0

Спасибо, этот второй скрипт очень изящный. Я немного взломаю его, чтобы заменить 'ls' на' find', поскольку Деннис Уильямсон предлагает избежать разбора ls и файлов обработки, которые не соответствуют шаблону. – caas

0

Сортировка имен файлов с человека 1 сортировка не удастся, если в имени файла есть символ новой строки.

Вместо этого мы должны использовать что-то вроде:

touch $'filename\nwith\777pesky\177chars.txt' # create a test file 

ls -1db * 

find ... -print0 | LC_ALL=C sort0 ... 

см:

Найти все используемые расширения в подкаталогах,

http://codesnippets.joyent.com/posts/show/2300

Смежные вопросы