LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 07-28-2007, 04:25 AM   #1
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Rep: Reputation: 0
Bash script to read file and alter lines depending on create date


Hey guys,

I need to have a bash script, but it's bothering me for days since I can't get it work.

It needs to do the following:
Read all user.conf files in a certain directory and it's subfolder (up to 1 level below).

The script will then read the files and search for the following line: date_created=Mon Jan 01 00:00:00 0000 if, the current date is 1 month ahead of the data in the file.

Or! The script looks at the files "last mofidied" date and check if it's older than 1 month


then the script should continue with the following.

Search for line: package=xxx and if it contains xxx then the script will change the following line: suspended=no to suspended=yes and saves the file.

OK, so now for my second thing, I need a batch script to reverse the above to as before the change.

I know this forum is not to script free scripts, and therefor; I am willing to pay. Also I would like to know if I don't get a loop when looking for the "last modified" date since the script changes the "modified date"!

If you already have such a script (doubtable) you can always mail me or add me on msn.

Last edited by ChristianHein; 07-28-2007 at 04:26 AM.
 
Old 07-28-2007, 04:36 AM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,017
Blog Entries: 54

Rep: Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764
Hello and welcome to LQ.

I know this forum is not to script free scripts, and therefor; I am willing to pay.
Actually it is and there's posted a few every day. If somebody asks nicely there's more than a few people willing to help. You should however show you're willing to invest yourself. In other words asking for (good: "I'd like help with X", bad: "Gimme X") handouts is considered reply unworthy and asking for help with homework is not allowed by the LQ Rules. Willingness to pay is even worse IMNSHO because that's not what the LQ Community is about. If you want to pay please consider contributing to LQ.

That said
I need to have a bash script, but it's bothering me for days since I can't get it work.
posting what you got helps people help you quicker, easier.

Last edited by unSpawn; 07-28-2007 at 04:38 AM.
 
Old 07-28-2007, 04:44 AM   #3
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Ok that sounds fair unSpawn, The thing I already managed to get is to search for files, but that's off a tutorial posted here. I'm not trying to let others solve the problems, it's just way out of my league. LQ is a great support to the community (a community by itself) Really appreciate the things you do.

Last edited by ChristianHein; 07-28-2007 at 04:47 AM.
 
Old 07-28-2007, 05:12 AM   #4
jschiwal
Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654
You can locate files prior to a certain day with the -mtime option of find. The first option could be -maxdepth <depth> to limit how many directory levels that find recurses.

If you extract the creating date from the file, use the "date" command with the -d '<extracted-date>' argument and the -s '%s' option to make subtraction easier. For example:
Code:
echo $(( ( $(date +'%s') - $(date +'%s' -d 'Mon Jul 01 00:00:00 2007'))/60/60/24 ))
You might want to print out the manpage for the date command:
man -t date | lpr

I would highly recommend installing the source for the findutils package and producing a PostScript or PDF manual from the texinfo source to produce the "Finding Files" (find.pdf) manual. The find command is one of those swiss army knife commands that you can't do without.

Extracting the dates from the files could be done in awk or sed. Grep is usually used to return a line containing the file.

Last edited by jschiwal; 07-28-2007 at 05:34 AM.
 
Old 07-30-2007, 01:08 PM   #5
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Ok, i now know to find the files, anyone else with some suggestions? I hate to be a bother, but i'd rather have someone make the script as i'm very new to this. Thanks in advance guys.
 
Old 07-30-2007, 04:18 PM   #6
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,017
Blog Entries: 54

Rep: Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764
Code:
#!/bin/sh
# Purpose: doSomething
# Args: yes :-]
# Deps: Bash, GNU utils
# Run from: scheduler or manually

# Prepstage functions
progn=${0//*\//}
# Set debug mode when testing:
set -x

help() { echo "${progn}: --doSomething targetname"; exit 1; }
rand () { randVal=$(echo "$(date) ${RANDOM} $$"|sha1sum); RANDOMV="${randVal:0:40}"; }

# Where we lay our hat, that be our home.
TARGETDIR="/etc/certaindir"
if [ ! -d "$TARGETDIR" ]; then
        echo "${progn}: no DIR named \""$TARGETDIR"\"."
        exit 1
fi

# We like variables
if [ $# -eq 2 ]; then
        case "$1" in
                --doSomething)  # Let's do something on this target
                                shift 1; TARGET="$1"
                                if [ -z "$TARGET" ]; then help; fi      
                                ;;
                -h*|--h*)       # Somebody needs help
                                help
                                ;;
                *)              # Let's do nothing
                                help
                                ;;
        esac
else help
fi

# Set the date, we're not using %H%M%S resolution and we don't consider yrs either :-]
CHECKDATE=`date '+%a %d %b' --date="1 month ago"`

# Read all user.conf files in a certain directory and it's subfolder (up to 1 level below).
find "$TARGETDIR" -type f -iname \*.conf --maxdepth 1| while read FILEN; do
        # The script will then read the files and search for the following line:
        # date_created=Mon Jan 01 00:00:00 0000
        CONFDATE=`grep ^date_created= "${FILEN}"`; CONFDATE=(${CONFDATE//*=/})
        unset CONFDATE[3] CONFDATE[4]; CONFDATE="${CONFDATE[*]}"
        # if, the current date is 1 month ahead of the data in the file.
        if [ "${CONFDATE}" != "${CHECKDATE}" ]; then
                echo "${progn}: nothing to do in "${FILEN}" for "${TARGET}"."
        else
                # Let's do something
                # Search for line: package=xxx
                grep -q ^package="${TARGET}" "${FILEN}"
                case "$?" in
                        0)      # and if it contains xxx then the script will change
                                # the following line: suspended=no to suspended=yes and saves the file.
                                echo -en "${progn}: got "${TARGET}" in "${FILEN}": "
                                UMASK=027; DAC=($(stat -c '%a %g %u' "${FILEN}")); echo -en "changing: "
                                sed -e "s|suspended=no|suspended=yes|g" "${FILEN}" > "${FILEN}.${RANDOMV}" && \
                                install -u ${DAC[2]} -g ${DAC[1]} -m ${DAC[0]} "${FILEN}.${RANDOMV}" "${FILEN}" && \
                                echo "OK." || echo "FAILED, see "${FILEN}.${RANDOMV}"."
                                ;;
                        *)
                                ;;
                esac
        fi
done

exit 0
I. It may look OK but in essence it is just thrown together quickly. It's a kludge. It may or may not work: YMMV(VM) as usual.
II. Jschiwal gave you some solid hints about stuff you should read up on. I can imagine it's a daunting for a scripting newbie, but how else could you validate or correct a script someone has offered you? It may even Do Stuff that it doesn't advertise.
III. These could be helpful too:
Code:
function help() { echo "Bash scripting guides:
http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html 
http://www.tldp.org/LDP/Bash-Beginners-Guide/html/index.html 
http://www.tldp.org/LDP/abs/html/ 
http://wooledge.org/mywiki/BashFAQ?action=show&redirect=BashFaq 
http://wooledge.org/mywiki/BashPitfalls"; }
 
Old 07-31-2007, 10:27 AM   #7
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Thank you unspawn, it makes more sense to me now. Unfortunatly the script didn't work, as you've feared. I get the following error:

Code:
+ TARGETDIR=/usr/local/directadmin/data/users/
+ '[' '!' -d /usr/local/directadmin/data/users/ ']'
+ '[' 0 -eq 2 ']'
+ help
+ echo 'telehosting.sh: --doSomething targetname'
telehosting.sh: --doSomething targetname
+ exit 1
 
Old 07-31-2007, 12:41 PM   #8
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,017
Blog Entries: 54

Rep: Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764
That's no error, that's *help*. It shows you what arguments you should provide.
 
Old 08-02-2007, 03:51 AM   #9
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Ok i'm getting closer. But it appears that the script doesn't change anything after 1 month is passed.

Code:
+ read FILEN
++ grep '^date_created=' /usr/local/directadmin/data/users/testje/user.conf
+ CONFDATE='date_created=Thu May 26 18:27:32 2007'
+ CONFDATE=(${CONFDATE//*=/})
+ unset 'CONFDATE[3]' 'CONFDATE[4]'
+ CONFDATE='Thu May 26'
+ '[' 'Thu May 26' '!=' 'Mon Jul 02' ']'
+ echo 'telehosting2.sh: nothing to do in /usr/local/directadmin/data/users/testje/user.conf for .'
telehosting2.sh: nothing to do in /usr/local/directadmin/data/users/testje/user.conf for .
Note, at first the script didn't find any file so I had to hardcode the find command to: find /usr/local/directadmin/data/ -type f -iname user.conf Which I think saves some memory when executing the script.

Last edited by ChristianHein; 08-02-2007 at 03:53 AM.
 
Old 08-02-2007, 11:50 AM   #10
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,017
Blog Entries: 54

Rep: Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764
Since you show persistence I rewrote the script a wee bit. (OK, the hardcoding part is stupid, I should use "getopt" instead but it'll do for now.) To see what changed save it and then "diff --side-by-side oldscript newscript | less". It does not remove the backups on failure but YMMV(VM) still.

Code:
#!/bin/sh
# Purpose: doSOmething
# Args: yes :-]
# Deps: Bash, GNU utils
# Run from: scheduler or manually

# Prepstage functions
progn=${0//*\//}
# Set debug mode when testing:
set -x

help() { echo "${progn}: --doSomething targetname"; exit 1; }
rand () { randVal=$(echo "$(date) ${RANDOM} $$"|sha1sum); RANDOMV="${randVal:0:40}"; }

# Where we lay our hat, that be our home.
TARGETDIR="/usr/local/directadmin/data"
if [ ! -d "$TARGETDIR" ]; then
        echo "${progn}: no DIR named \""$TARGETDIR"\"."
        exit 1
fi

# We like variables
if [ $# -eq 2 ]; then
        case "$1" in
                --doSomething)  # Let's do something on this target
                                shift 1; TARGET="$1"
                                if [ -z "$TARGET" ]; then help; fi
                                ;;
                -h*|--h*)       # Somebody needs help
                                help
                                ;;
                *)              # Let's do nothing
                                help
                                ;;
        esac
else help
fi

# Set the date value using epoch. You know, the stuff they take in the Tour De France ;-p
CHECKDATE=`date --date="1 month ago" +%s`

# Read all user.conf files in a certain directory and it's subfolder (up to 1 level below).
find "$TARGETDIR" -type f -iname \*.conf -maxdepth 1| while read FILEN; do
        # The script will then read the files and search for the following line:
        # date_created=Mon Jan 01 00:00:00 0000
        CONFDATE=`grep ^date_created= "${FILEN}"`; CONFDATE=(${CONFDATE//*=/})
        unset CONFDATE[3] CONFDATE[4]; CONFDATE=`date --date="${CONFDATE[*]}" +%s`
        # if, the current date is 1 month ahead of the data in the file.
        if [ -z "$CONFDATE" -o $CONFDATE -ge $CHECKDATE ]; then
                echo "${progn}: nothing to do in "${FILEN}" for "${TARGET}"."
        else
                # Let's do something
                # Search for line: package=xxx
                grep -q ^package="${TARGET}" "${FILEN}"
                case "$?" in
                        0)     # and if it contains xxx then the script will change
                                # the following line: suspended=no to suspended=yes and saves the file.
                                echo -en "${progn}: got "${TARGET}" in "${FILEN}": "
                                UMASK=027; DAC=($(stat -c '%a %g %u' "${FILEN}")); echo -en "changing: "
                                sed -e "s|suspended=no|suspended=yes|g" "${FILEN}" > "${FILEN}.${RANDOMV}" && \
                                install -u ${DAC[2]} -g ${DAC[1]} -m ${DAC[0]} "${FILEN}.${RANDOMV}" "${FILEN}" && \
                                { echo "OK."; rm -f "${FILEN}.${RANDOMV}"; } \
                                || echo "FAILED, see "${FILEN}.${RANDOMV}"."
                                ;;
                        *)
                                ;;
                esac
        fi
done

exit 0
 
Old 08-03-2007, 03:46 AM   #11
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Hmmm i get the following error:
Code:
telehosting3.sh: got  in /usr/local/directadmin/data/users/testje/user.conf: changing: install: invalid option -- u
Try `install --help' for more information.
FAILED, see /usr/local/directadmin/data/users/testje/user.conf..
Not quite sure what it means though, I did change the scrpt a bit, i removed the -maxdepth since that didn't and instead i just moved the file 1 level above and that works fine. Also I don't see the package defined in the script. The package should really be "telehosting" instead of "xxx" which was just an example. All I see is
Code:
grep -q ^package="${TARGET}" "${FILEN}"
Where the target en filen refers to some code above.

So i was wondering, isn't it possible to write the script like:
find /usr/local/directadmin/data -name *user.conf*
touch (the above)
(open vi editor) ?date_created (compare to current date) some if and else statement which resolves to the below (if positive, 1 month old else die). Look for package=telehosting if it contains that package change suspended=no to suspended=yes
:wq! and repeat for the next file in line. Unfortunatly i'm not a big star when it comes to vi I know it's possible to replace a line when it contains a match but the date thing is still blurry to me.
 
Old 08-03-2007, 11:24 AM   #12
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,017
Blog Entries: 54

Rep: Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764Reputation: 2764
Code:
#!/bin/bash -
# Purpose: doSomething
# Deps: Bash, GNU utils
# Run from: scheduler or manually
TARGETDIR="/usr/local/directadmin/data"; TARGET="telehosting"
CHECKDATE=`date --date="1 month ago" +%s`
find "$TARGETDIR" -type f -iname \*.conf | while read FILEN; do
 CONFDATE=`grep ^date_created= "${FILEN}"`; CONFDATE=(${CONFDATE//*=/})
 unset CONFDATE[3] CONFDATE[4]; CONFDATE=`date --date="${CONFDATE[*]}" +%s`
 if [ $CONFDATE -ge $CHECKDATE ]; then echo "nothing to do in ${FILEN}"
 else grep -q ^package="${TARGET}" "${FILEN}" && \
 sed -i -e "s|suspended=no|suspended=yes|g" "${FILEN}"; fi; done
exit 0
I'm done with this.
 
Old 08-04-2007, 04:17 AM   #13
ChristianHein
LQ Newbie
 
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7

Original Poster
Rep: Reputation: 0
Thank you so much unspawn, that worked for me I'll see what I can do about supporting this great website/community. Again thank you.
 
Old 08-04-2007, 05:39 AM   #14
frenchn00b
Senior Member
 
Registered: Jun 2007
Location: E.U., Mountains :-)
Distribution: Debian, Etch, the greatest
Posts: 2,546

Rep: Reputation: 50
Quote:
Originally Posted by ChristianHein
Hey guys,

I need to have a bash script, but it's bothering me for days since I can't get it work.

It needs to do the following:
Read all user.conf files in a certain directory and it's subfolder (up to 1 level below).

The script will then read the files and search for the following line: date_created=Mon Jan 01 00:00:00 0000 if, the current date is 1 month ahead of the data in the file.

Or! The script looks at the files "last mofidied" date and check if it's older than 1 month


then the script should continue with the following.

Search for line: package=xxx and if it contains xxx then the script will change the following line: suspended=no to suspended=yes and saves the file.

OK, so now for my second thing, I need a batch script to reverse the above to as before the change.

I know this forum is not to script free scripts, and therefor; I am willing to pay. Also I would like to know if I don't get a loop when looking for the "last modified" date since the script changes the "modified date"!

If you already have such a script (doubtable) you can always mail me or add me on msn.
awk is a wonderful tool, that can read write files / scripts / ...
http://www.gnu.org/software/gawk/manual/
learn this: it 's worth to do
you ll be glad of this powerful tool
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
bash: read multiple lines in a file 300zxkyle Programming 7 07-29-2007 04:38 AM
bash script that can read lines of text palceksmuk Programming 1 12-25-2005 03:49 AM
bash: read lines from a configuration script ldp Programming 2 09-23-2005 11:58 AM
Can't get lines of a file with a Bash script.. barisdemiray Programming 2 08-11-2004 12:42 PM
howto create a file based on date in bash rohan208 Linux - Newbie 2 05-07-2004 03:54 PM


All times are GMT -5. The time now is 08:56 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration