Как найти отсутствующие файлы в определенном диапазоне дат?

Вот подправленная версия ответа Richard Cook's answer для исправления проблем с экранированием на tmux 2.1

#!/bin/bash
tmux -f /dev/null -L temp start-server \; list-keys | \
    sed -r \
    -e "s/(bind-key.*\s+)([\"#~\$])(\s+)/\1\'\2\'\3/g" \
    -e "s/(bind-key.*\s+)([\'])(\s+)/\1\"\2\"\3/g" \
    -e "s/(bind-key.*\s+)([;])(\s+)/\1\\\\\2\3/g" \
    -e "s/(command-prompt -I )#([SW])/\1\"#\2\"/g" \
    -e "s/(if-shell -F -t = )#([^ ]+)/\1\"#\2\"/g" \
    > ~/.tmux.reset.conf                              

Добавьте следующие строки в начало .tmux.conf

unbind-key -a
source-file ~/.tmux.reset.conf

6
14.08.2017, 19:23
5 ответов
# presuming that the files are e. g. template-2017-07-01-16:

# To test a given date
for file in template-2017-07-01-{00..23}; do
  if ! [[ -f "$file" ]]; then
    echo "$file is missing"
  fi
done

# To test a given year
year=2017
for month in seq -w 1 12; do
    dim=$( cal $( date -d "$year-$month-01" "+%m %Y" | awk 'NF { days=$NF} END {print days}' )
    for day in $(seq -w 1 $dim); do
        for file in template-${year}-${month}-${day}-{00..23}; do
           if ! [[ -f "$file" ]]; then
             echo "$file is missing"
           fi
        done
    done
done
9
27.01.2020, 20:20

В системе GNU:

#! /bin/bash -
ret=0
start=${1?} end=${2?}
t1=$(date -d "$start" +%s) t2=$(date -d "$end" +%s)

for ((t = t1; t < t2; t += 60*60)); do
  printf -v file '%(%F-%H)T' "$t"
  if [ ! -e "$file" ]; then
    printf >&2 '"%s" not found\n' "$file"
    ret=1
  fi
done
exit "$ret"

Обратите внимание, что в день перехода на зимнее время (в часовых поясах, в которых реализовано летнее время) вы можете дважды получить сообщение об ошибке, если для часа перехода отсутствует файл. Исправьте $TZна UTC0, если вы хотите 24 часа в сутки для каждого дня (например, если все, что создает эти файлы, использует время UTC вместо местного времени).

6
27.01.2020, 20:20

Почему бы не использовать egrep? затем вы можете регулярно выражать его так, как хотите.

 egrep (2017-07-0[1-2]-\d\d$) *file name here*| tail     

Регулярное выражение может быть немного неправильным — извините.

0
27.01.2020, 20:20

Использование:./diff_date.sh 2017-08-30-00 2017 -09-02-00

#!/bin/bash

# This processing is needed, because `date` require 2017-08-30 00 format,
# not 2017-08-30-00. So, last dash is replacing by space in here.
start=$(sed 's/-/ /3' <<< "$1")
end=$(sed 's/-/ /3' <<< "$2")

while [[ "$start" != "$end" ]]; do
    # Returns dash back to its place and checks - does this file exist. 
    if [ ! -f "${start/ /-}" ]; then 
        echo "${start/ /-}"
    fi  
    # Performance of this code can be improved, by calling `date` only when
    # day is changing, not the every hour.
    start=$(date -d "${start} + 1 hour" "+%F %H")
done

Тестирование:

# make files
$ touch 2017-08-{30..31}-{03..23}; touch 2017-09-{01..02}-{03..23}
$
$ ./diff_date.sh 2017-08-30-00 2017-09-02-00
##### Output - missing files. #####
2017-08-30-00
2017-08-30-01
2017-08-30-02
2017-08-31-00
2017-08-31-01
2017-08-31-02
2017-09-01-00
2017-09-01-01
2017-09-01-02
1
27.01.2020, 20:20

Как насчет команды, как показано ниже:

 grep -Fvf <(find * -type f \( -name "2017-07-02-00" $(printf " -o -name %s" 2017-07-02-{01..23}) \)) \
           <(printf "%s\n" 2017-07-02-{00..23})
ls
2017-07-02-01  2017-07-02-06  2017-07-02-08  2017-07-02-14  2017-07-02-19
2017-07-02-04  2017-07-02-07  2017-07-02-11  2017-07-02-15  2017-07-02-22

Вывод после выполнения команды:

2017-07-02-00
2017-07-02-02
2017-07-02-03
2017-07-02-05
2017-07-02-09
2017-07-02-10
2017-07-02-12
2017-07-02-13
2017-07-02-16
2017-07-02-17
2017-07-02-18
2017-07-02-20
2017-07-02-21
2017-07-02-23

Выше мы генерируем все возможные 24 файла, используя printfи передаем их в findего -nameпараметр, который printfтакже помогает ей, затем с помощью команды grepмы печатаем, что эти файлы существуют в наш образец , но findих не нашел.

4
27.01.2020, 20:20

Теги

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