String processing to compare dates


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting String processing to compare dates
# 1  
Old 07-31-2011
String processing to compare dates

Hi all,

I have been scripting a shell script to allow me to easily create htaccess users and add them to existing htaccess groups etc.

However, the main part of the script that I am trying to accomplish is to store additional metadata in comments in the htpasswd file. I am trying to store an expiry date in the comments, such that the htpasswd file can be scanned and any users with expiry dates that are in the past can be deleted.

The syntax of the htpasswd file with expiry date metadata is:
Code:
username:ABCDEFG   (tab)   # comment [exp:YYYY-MM-DD]

I am now trying to write the script to scan the htpasswds file and delete expired users. This is what the script needs to do:
  1. Check each line in htpasswds
  2. If the user in htpasswds has no comment, or if the expiry date of the current user is a date that has not yet passed, then skip this user.
  3. Else, delete this user from the htpasswds now.
  4. Scan the htgroups file for all instances of this user and delete them (being weary of comments in the file)
  5. If, after deleting the user from a group, the group is left empty, delete the group (as well as a few lines of comments appearing above the group) from htgroups.
This is my current code to achieve the above steps. I stopped however because I am sure there is a more efficient way to achieve this (Perl, Awk, Sed, ..., I'm not really sure).

Code:
# loop through each line of htpasswd
(
    while read line; do            
        # extract the username from the line
        line_user=$(echo `echo "$line" | cut -d: -f1`)
        [ -n "$VERBOSE" ] && echo "Checking expiry of user '$line'" >&2
        
        # extract the expiry date from the line
        line_date=$(echo `echo "$line" | grep -o "\[exp:[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\]" | grep -o "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"`)

        if [ -n "$line_date" ]; then
            EXPIRED=
            
            # break the expiry date into a year, month and date
            line_year=$(echo `echo "$line_date" | cut -d- -f1`)
            line_month=$(echo `echo "$line_date" | cut -d- -f2`)
            line_date=$(echo `echo "$line_date" | cut -d- -f3`)
            
            if [ $line_year -lt $today_year ]; then
                EXPIRED=1
            elif [ $line_year -eq $today_year ]; then
                if [ $line_month -lt $today_month ]; then
                    EXPIRED=1
                elif [ $line_month -eq $today_month ]; then
                    if [ $line_date -lt $today_date ]; then
                        EXPIRED=1
                   fi
                fi
            fi
            
            if [ -z "$EXPIRED" ]; then
                # not expired, output the user back to htpasswds
                echo "$line"
            else
                [ -n "$VERBOSE" ] && echo "User has expired. Deleting..." >&2
                
                echo "Haven't yet implemented deleting user from htgroups. This needs to be done manually!" >&2
                # also delete the user from htgroups
                #(
                #    while read line2; do
                #        #new_group=$(echo `echo "$line2" | grep -o "^[^#].*:*\[ $line_user \]" | grep -o "^[^#].*:*\[$line_user \]" | grep -o "^[^#].*:*\[ $line_user\]"sed 's/^[^#].*:$/'`)
                #    done < $HTGROUPS
                
                #) > $HTGROUPS.tmp    
            fi
        else
            # user doesn't have an expiry date, output the user back to htpasswds
            echo "$line"
        fi
    done < $HTPASSWD
) > $HTPASSWD.tmp

# move temp file
rm -f $HTPASSWD
mv $HTPASSWD.tmp $HTPASSWD

# 2  
Old 07-31-2011
Try something like this:
Code:
EXPDATE='2011-10-11'
perl -lne '/\[exp:([\d-]+)\]/ ? ($1 gt "'"$EXPDATE"'" && print) : print' htpasswd

PS
It's only safe if you hardcode EXPDATE, do not get from an untrusted source.

Last edited by yazu; 08-01-2011 at 12:23 AM..
# 3  
Old 08-01-2011
Quote:
Originally Posted by yazu
Try something like this:
Code:
EXPDATE='2011-10-11'
perl -lne '/\[exp:([\d-]+)\]/ ? ($1 gt "'"$EXPDATE"'" && print) : print' htpasswd

PS
It's only safe if you hardcode EXPDATE, do not get from an untrusted source.
Thank! That works great.

The other (harder) part, however, is to also delete these users from htgroups (I'm guessing this would need to be done before deleting the users from htpasswd)
# 4  
Old 08-01-2011
I'm sure it may be easy and this can be done at the same time like this (pseudo-code):
Code:
perl -lne '/(user).*(date)/ ? (right_date($2) && ++$users{$1} && print) : print;
END {
  remove all users from keys %users from htgroups
}

But please, if you want to get real help give real examples of your input.
# 5  
Old 08-01-2011
Quote:
Originally Posted by yazu
I'm sure it may be easy and this can be done at the same time like this (pseudo-code):
Code:
perl -lne '/(user).*(date)/ ? (right_date($2) && ++$users{$1} && print) : print;
END {
  remove all users from keys %users from htgroups
}

But please, if you want to get real help give real examples of your input.
Thanks for your assistance. I am not familiar with Perl but I will give this a go.

Also, here is some examples of the input:

htpasswd:
Code:
osFtsoPO:ZjCqTssMg26GU
zNXOutfZ:K6wkNAmazZpgQ
iNTdEl4A:fbvbYtt2CG7GE
LM6G4M5r:JvaytqY5iQT6s
7b5ZVtfC:1YOTiDP7QMu46
ssUBkol0:Xpcxzcpkea00M
o1JvNOqA:hS7KXYCVPVZzk
Wjg28Q7Z:txvKZULw6IGQY
9BYLeZqm:o.brY4eMwo83Y
iUyLbtL4:2BPsVeT6INCjU
gW8Ts5QB:ES7wPmhv5zWkc   # [exp:2011-08-07]
xeI2BlBF:5UkRPOAmmvYQ6   # [exp:2011-08-07]
DqgUnQq7:wODD.q7G6tBG.   # [exp:2011-08-07]
APr62acP:bwSs.xqxzVhf2   # [exp:2011-08-07]
m8eJuHgJ:UGnggpDogE0mE   # [exp:2011-08-07]
qbIv1jvM:TEtfj3paSfXI6   # [exp:2011-08-07]
StcEfJjw:Yadibnucypobw   # [exp:2011-08-07]
ZZ7XQnKZ:k50CN9MTktDZM   # [exp:2011-08-07]
J4WJgqzb:648PPzACrHXU2   # [exp:2011-08-07]
i19tECpj:PBRPcIwa/Xrh.   # [exp:2011-08-07]
w9LVCtgF:sE0f4YvY2ZbFo   # [exp:2011-07-27]
np6EplLx:o/RoBYsDNWOa.   # [exp:2011-07-27]
lH9BiLaD:qFIPpYcg/uwxc   # [exp:2011-07-27]
Tq7bxObg:NNWjVwLvgEM2.   # [exp:2011-07-27]
Sprx0OHu:XizJkBT4U9CiE   # [exp:2011-07-27]
2d8NI6Sl:05CBhrUFVC7oI   # [exp:2011-07-27]
2eUHSw2J:gFLMdtYDQ41Q2   # [exp:2011-07-27]
GrVq3bXQ:BOcpjHrkFp6Lg   # [exp:2011-07-27]
lhDpIeid:wb0yrVMlQ9k7.   # [exp:2011-07-27]
XqxThbtH:elmYRVI8nI45E   # [exp:2011-07-27]
EVu0Y1E6:5eyhQUfeV6ayQ   # Comment [exp:2011-07-31]
IMHJb2s5:O13UEZuE/33Zo   # Comment [exp:2011-07-31]
Px1ck3Me:M1A.BkDbP.55.   # Comment [exp:2011-07-31]
hgAXHHk5:hU0pejGjTMG9M   # Comment [exp:2011-07-31]
abcd:VIEzA5I5IxEMc   # Comment [exp:2011-07-31]

htgroups:
Code:
################################################
# Group: test
# Members: (unknown)
test: f5JJTB6g WJXn6PHy d9NME1OB 6kKq8P8G g2EMf77J fWegqo2e XmexEc5S vgxH2txy hFFBvK35 6aLtuE8h z2jSdCMC rVmIJGoI JbZVO119 vUp33XWQ Wo7rP4qW A4Fb6E4w S3UpACU4 m6zXlxTq cuq6Pgbp 0FI0jXp4

################################################
# Group: test2
# Members: (unknown)
test2: atcF6fv6 rWTTjVAn NDjgFwZs eepg7TvA HaCx3x2a Sda2JzbW q8I6KL9V 7l6MSr7b tjg3AjoW 1NuSi63A abc

################################################
# Group: test3
# Members: (unknown)
test3: abcd

################################################
# Group: group1
# Members: (unknown)
group1: i2KWJtCH 1pHpcx7B YGDu8AcS WaTE3DMx KBBG0dPq fpiaRmLl oAQKdEDq oqbkUmUI nB0LQE4Y c4HhXeFz

If user "abcd" was removed from htpasswd, then the text:
Code:
################################################
# Group: test3
# Members: (unknown)
test3: abcd

should be removed from htgroups.
# 6  
Old 08-01-2011
Sorry, I forget to add about "real examples" - remove all confidential information if there is.
Ok, for trying to write the script this will be enough:
Code:
qwerty:2BPsVeT6INCjU
abcd:ES7wPmhv5zWkc   # [exp:2011-08-07]
zxcv:5eyhQUfeV6ayQ   # Comment [exp:2011-09-31]

One more question. What to do if we have a such record in htgroups (and only abcd is expired):
Code:
################################################
# Group: group1
# Members: (unknown)
group1: abcd qwerty zxcv aaaa

# 7  
Old 08-01-2011
Quote:
Originally Posted by yazu
Sorry, I forget to add about "real examples" - remove all confidential information if there is.
Ok, for trying to write the script this will be enough:
Code:
qwerty:2BPsVeT6INCjU
abcd:ES7wPmhv5zWkc   # [exp:2011-08-07]
zxcv:5eyhQUfeV6ayQ   # Comment [exp:2011-09-31]

One more question. What to do if we have a such record in htgroups (and only abcd is expired):
Code:
################################################
# Group: group1
# Members: (unknown)
group1: abcd qwerty zxcv aaaa

Yeah all records are randomly generated. This file isn't in use.

If only abcd is removed: the output should be:

Code:
################################################
# Group: group1
# Members: (unknown)
group1: qwerty zxcv aaaa

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Compare Dates.

Hi All, I am entering StartDate and EndDate as parameters to script. Want to have an check saying, "If StartDate is greater than EndDate then don't execute the script". Pseudo Code: if then Execute script else exit 0 fi Can you please help me on the same? Thanks and... (4 Replies)
Discussion started by: Nagaraja Akkiva
4 Replies

2. HP-UX

Compare dates

Hi, I want to convert two datetime fields to find out if the difference is one hour, in linux I've done this by converting both the datetime values to unix epoch time and subtracting them to find out if the difference is more than 3600s, however this does not work in hp-ux. I've these... (3 Replies)
Discussion started by: Random_Net
3 Replies

3. Shell Programming and Scripting

The Best Way to Compare Dates

Hi to all. When you have to compare a lot of dates in a SH code, there is a way to directly compare? For example, how can I check if two dates differ in less than a week? Thank's for reading. (2 Replies)
Discussion started by: daniel.gbaena
2 Replies

4. Shell Programming and Scripting

compare dates

I want to compare a list of dates in a file with today's date & list only dates that are less than only 60 days old . please help . the date in the file are in format 11-FEB-2009 02-FEB-2009 26-JAN-2009 24-JAN-2009 13-JAN-2009 16-DEC-2008 10-DEC-2008 01-DEC-2008 25-NOV-2008 19-NOV-2008... (3 Replies)
Discussion started by: skamal4u
3 Replies

5. Shell Programming and Scripting

compare between the two dates

Hi all, How to check whether the given the two dates is minimal. example: Date 1 : 23-03-2008 with timestamp Date 2: 20-03-2008 With tmestamp I want to compare the twodates and which it gives the minimum date i wnat to get the output like this below output: the Date2 is... (1 Reply)
Discussion started by: balaji23_d
1 Replies

6. Shell Programming and Scripting

How to compare the dates..

Hi all, I've written a script which gives the below information... End Date&Time: 2008-10-21 10.54.37 Now i want to calculate this time with the current time.. and if its more than 48 hours past with the current time it should echo "48 Hours back" Please help me.. thanks in... (4 Replies)
Discussion started by: suri.tyson
4 Replies

7. Shell Programming and Scripting

compare dates...

hi all :) how can in compare yyyy/dd/mm with yyyy/dd/mm in perl i want the result like grater than or less than the given date... thanks in advance (3 Replies)
Discussion started by: i_priyank
3 Replies

8. Programming

How to compare dates in C/C++

Hi, Is there any system defined function to compare two dates in C/C++? Thanks (1 Reply)
Discussion started by: naan
1 Replies

9. Programming

How to compare two dates

Hi I am writing a unix program. In that, i should compare two dates. I would like to know how to compare two dates in unix-whether they are same or not. pls help (5 Replies)
Discussion started by: bankpro
5 Replies

10. Shell Programming and Scripting

compare two dates

I have a log file with date format like 10-Oct-02 13:20:29 ..... at the beginning of each line in the log file, and I need to grep data from this file to list the lines with date no longer than one days. I tried to use awk to do this but it looks very complicated to do it. Is there... (6 Replies)
Discussion started by: wchen
6 Replies
Login or Register to Ask a Question