简体   繁体   中英

Bash: find all files based on date range in file names

I have a directory with a lot of files named in the following date format:

YYYYMMDDHH00

with a com port number on the end. For example

202003240200COM10.txt
202003240300COM10.txt
202003240400COM10.txt

These files are generated every hour by a script and the names are always in the same format.

I want to use the "find" command to return a list of files within a date range that I specify in a script, for example all files between "1 hour ago" and "1 month ago". This script will be run at random times and I always want it to search between that date range relative to the current date, so I don't want any hard coded dates.

I can get the date for 1 hour ago and 3 months ago using the "date" command as so:

bash-4.4$ date --date "1 hour ago" +%Y%m%d%H00
202003241500
bash-4.4$ date --date "1 month ago" +%Y%m%d%H00
202002241600

But I am struggling to get this into the "find" command properly. I have tried the following:

for currentfile in *.txt
do
    filedate=${currentfile:0:12}
        file_date=$(date +%s -d "${filedate:0:8}${filedate:8:2}${filedate:10:2}${filedate12:2}")
        start_date=$(date +%s -d "1 month ago")
        end_date=$(date +%s -d "1 hour ago")

        if [[ $file_date -ge $start_date && $file_date -le $end_date ]]; then
                echo $currentfile
        fi
done

But the console output is just a flood of these errors, seemingly one for every file:

date: invalid date 201703190300
date: invalid date 201703190400
date: invalid date 201703190500
date: invalid date 201703190600
date: invalid date 201703190700
date: invalid date 201703190800
date: invalid date 201703190900
date: invalid date 201703191000
date: invalid date 201703191100
date: invalid date 201703191200
date: invalid date 201703191300
date: invalid date 201703191400
date: invalid date 201703191500
date: invalid date 201703191600
date: invalid date 201703191700
date: invalid date 201703191800
date: invalid date 201703191900

Please help :)

date -d expects a space between the date and time parts. The "CO" is not a valid part of a time stamp, so remove it (there was a typo in your original code which resulted in an unset variable) and delimit hours and minutes by colons:

file_date=$(date +%s -d "${filedate:0:8} ${filedate:8:2}:${filedate:10:2}")

I created test files using

touch 20200{1,2,3,4}2{3,4,5}0200COM{1,2,3}0.txt 

Running the following script

#!/bin/bash

start_date=$(date +%s -d "1 month ago")
end_date=$(date +%s -d "1 hour ago")

for currentfile in *.txt ; do
    file_date=$(date +%s -d "${currentfile:0:8} ${currentfile:8:2}:${currentfile:10:2}")

    if [[ $file_date -ge $start_date && $file_date -le $end_date ]]; then
        echo $currentfile
    fi
done

only the correct ones were printed:

202002250200COM10.txt
202002250200COM20.txt
202002250200COM30.txt
202003230200COM10.txt
202003230200COM20.txt
202003230200COM30.txt
202003240200COM10.txt
202003240200COM20.txt
202003240200COM30.txt

As correctly noted in the comments by Léa Gris , you can use the YYYYMMDDhhmm format directly and compare the timestamps as strings. This way you don't need to call date inside the loop at all:

#!/bin/bash

start_date=$(date +%Y%m%d%H%M -d "1 month ago")
end_date=$(date +%Y%m%d%H%M -d "1 hour ago")

for currentfile in *.txt ; do
    file_date=${currentfile:0:12}
    if [[ ! $file_date < $start_date && ! $file_date > $end_date ]]; then
        echo $currentfile
    fi
done

Note that the >= operator doesn't exist, so we have to use negated < .

As this question already got an answer, I might suggest an alternative approach which doesn't rely on correct file names. Instead, you could just read the meta data of your files and print them accordingly. The first date is the more recent one.

find . -mtime $(date +%s -d "1 hour ago") -mtime $(date +%s -d "1 month ago")

That might be more reliable and would work for other logging applications, as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM