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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
07-28-2007, 04:25 AM
|
#1
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Rep:
|
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.
|
|
|
07-28-2007, 04:36 AM
|
#2
|
Moderator
Registered: May 2001
Posts: 29,417
|
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.
|
|
|
07-28-2007, 04:44 AM
|
#3
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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.
|
|
|
07-28-2007, 05:12 AM
|
#4
|
LQ Guru
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733
|
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.
|
|
|
07-30-2007, 01:08 PM
|
#5
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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.
|
|
|
07-30-2007, 04:18 PM
|
#6
|
Moderator
Registered: May 2001
Posts: 29,417
|
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"; }
|
|
|
07-31-2007, 10:27 AM
|
#7
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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
|
|
|
07-31-2007, 12:41 PM
|
#8
|
Moderator
Registered: May 2001
Posts: 29,417
|
That's no error, that's *help*. It shows you what arguments you should provide.
|
|
|
08-02-2007, 03:51 AM
|
#9
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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.
|
|
|
08-02-2007, 11:50 AM
|
#10
|
Moderator
Registered: May 2001
Posts: 29,417
|
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
|
|
|
08-03-2007, 03:46 AM
|
#11
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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.
|
|
|
08-03-2007, 11:24 AM
|
#12
|
Moderator
Registered: May 2001
Posts: 29,417
|
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.
|
|
|
08-04-2007, 04:17 AM
|
#13
|
LQ Newbie
Registered: Jul 2007
Location: Netherlands
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
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.
|
|
|
08-04-2007, 05:39 AM
|
#14
|
Senior Member
Registered: Jun 2007
Location: E.U., Mountains :-)
Distribution: Debian, Etch, the greatest
Posts: 2,561
Rep:
|
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
|
|
|
All times are GMT -5. The time now is 02:56 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|