Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

#!/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

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.

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top