Bash script to read file and alter lines depending on create date
Linux - GeneralThis 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.
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.
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.
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.
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.
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:
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.
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.
#!/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:
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.
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
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.