views:

90

answers:

5

Greetings,

I need to store the filename of a log into a variable so my script can perform some checks on the daily log files. These logs always have a different name because they have a timestamp in the name. Currently I'm using a hodge podged method that pipes an ls command to sed, sort, cut, and tail in order to get the name out.

CRON_LOG=$(ls -1 $LOGS_DIR/fetch_cron_{true,false}_$CRON_DATE*.log 2> /dev/null | sed 's/^[^0-9][^0-9]*\([0-9][0-9]*\).*/\1 &/' | sort -n | cut -d ' ' -f2- | tail -1 )

UPDATE:

$CRON_DATE is supplied as an argument to the script. It is the date (to the day) that the log was created on. Sometimes multiple logs will exist for the same day so I want this to get the most recent one.

Some typical filenames:
fetch_cron_false_031810090452.log
fetch_cron_true_031310090001.log
etc...

Please keep in mind that this works as is. I just think it is ugly and am trying to find a better way to pull it off.

I'm pretty sure I kluged this together from some stuff I found google a few months ago. it works now but I'm not really happy with the technique. I have some ideas about how to do this better but I have had great success on this site before and thought it might be best to refer to the stackoverflow gods first. All answers are greatly appreciated.

Thanks, Ryan

+1  A: 

After you parse a log file, do something to mark that it has been processed, such a renaming it or moving it to a different folder. This way it won't matter when the file was created, only that it hasn't been parsed yet.

I would also suggest using a more high level scripting language.

mikerobi
+1  A: 

How about

CRON_LOG=$(ls -c $LOGS_DIR/fetch_cron_*$CRON_DATE* | head -1)

EDIT: You're right bta, I should have caught that. Fixed.

Beta
That would get the most recent log, but I think the OP wants to get the most recent log from a specified date (passed in via `$CHRON_DATE`).
bta
Much cleanre than what I'm doing now. Thanks! :D
SDGuero
A: 

you can change your date to sortable by prefixing the year in front, then do

CRON_LOG=$(ls ${LOGS_DIR}/fetch_cron_{false,true}_${CRON_DATE}*.log| tail -1)
ghostdog74
That wouldn't work as-is because all `"false"` dates would be alphabetized before any of the `"true"` dates, regardless of whether the year is prefixed or not. You would need another step to strip out the date from the text.
bta
please note that OP mentioned his command works as is.
ghostdog74
+1  A: 
#!/bin/bash
shopt -s nullglob

last=
for file in "$LOGS_DIR"/fetch_cron_{false,true}_"$CRON_DATE"*.log
do
  last="$file"
done

if [ -n "$last" ]
then
  echo "$last"
else
  echo "No match found" >&2
  exit 1
fi
Ignacio Vazquez-Abrams
Hmm. This is interesting... I like the trap and will think about this further. Thanks.
SDGuero
+1  A: 

For starters, try:

FILELIST=`ls -1 $LOGS_DIR/fetch_cron_{true,false}_$CRON_DATE*.log`
CRON_LOG=`echo $FILELIST | tr -d [:alpha:][:punct:] | sort -n | tail -1`

That gets rid of cut and trades the sed regular expression for a more-readable (IMO) call to tr. Splitting it into two lines helps with the clarity as well.

If you don't have any other files in $LOGS_DIR with extremely similar filenames (which usually happens if you keep the logs in question in their own folder), you can replace the parameter to ls with something simpler like $LOGS_DIR/fetch_*_$CRON_DATE*.log. For the sake of simplicity, don't make that line more complicated than required to ensure you get only the files you need.

bta
Thanks Bta. I picked yours first but then saw Beta's below (that you helped fix) which also worked. I'm going to use that solution but thank you for the help.
SDGuero