Search code examples
bashgetopts

Bash Script using getopts - use directory as argument


Okay, so I've got a script which I'm using to parse various log files with different columns and values. I've been trying to use getopts to allow my script to run the parsing on the files in one directory, and save the output to another directory. Essentially the command is (should be):

./script.sh -i /absolute/input/dir/ -o /absolute/output/dir/

Currently, if the script is in the directory with the log files, it will

check the first 4 and last 4 of each file, based on these results parse the file in a certain way, output the modifications to the assigned output dir, move on to the next file, finish.

Now, if I move the script outside of the log directory, I can't seem to get it to perform any action on the files.

Here's an example of my code:

#!/bin/bash
while getopts ":i:o:" opt; do
 case $opt in
  i)
   indir="$OPTARG"
   ;;
  o)
   outdir="$OPTARG"
   ;;
  \?)
   echo "invalid option"
   exit 0
  esac
done
shift $((OPTIND-1))

for f in *.log
do
  shopt -s nocasematch
  f4l4="${f:0:4}${f:${#f}-4}"
  if [[ "${f4l4}" = "this.log" ]]; then
    tr -cd "[:print:]\n" < $f | awk -F, 'BEGIN{OFS=FS}for(i=6,i<8;i++) $i=sprintf(%02X,$i)}1' > $outdir$f.csv
    sed -i '1icolumn1,column2,column3,column4,5,6,7,8,etc' $outdir$f.csv
  elif [[ "${f4l4}" = "that.log" ]]; then
    parse log file another way < $f | sed this and that > $outdir$f.csv1

  fi
done

So I have tried using the $indir variable within the for statement ($indir$f instead of $f) but that didn't work. If I echo $f then I can see all of the files in the directory, but the script just won't do anything.

In short, I want to use getopts to specify an input directory which contains the files to be edited, and the output directory for the edited files to be saved.

Thoughts?


Solution

  • I believe the problem is with this:

    f4l4="${f:0:4}${f:${#f}-4}"
    

    If f includes the path, then you're trimming from the whole path, not just the filename, so this is never true:

    [[ "${f4l4}" = "this.log" ]]
    

    Here's a fix, starting at for f in *.log...:

    for p in $indir*.log ## <-- change "for f in *.log" to this
    do
      f=`basename "$p"` ## <-- new
      ...
      if [[ "${f4l4}" = "this.log" ]]; then
        tr -cd "[:print:]\n" < $p  ## <-- change ($f to $p)
        ...
      elif [[ "${f4l4}" = "that.log" ]]; then
        parse log file another way < $p ## <-- change ($f to $p)