Сценарий Bash с использованием getopts - использовать каталог в качестве аргумента

Итак, у меня есть скрипт, который я использую для анализа различных файлов журналов с разными столбцами и значениями. Я пытался использовать getopts, чтобы позволить моему сценарию запускать синтаксический анализ файлов в одном каталоге и сохранять вывод в другом каталоге. По сути, команда (должна быть):

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

В настоящее время, если скрипт находится в каталоге с лог-файлами, он

проверить первые 4 и последние 4 каждого файла, на основе этих результатов разобрать файл определенным образом, вывести изменения в назначенный выходной каталог, перейти к следующему файлу, закончить.

Теперь, если я перемещаю сценарий за пределы каталога журнала, я не могу заставить его выполнять какие-либо действия с файлами.

Вот пример моего кода:

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

Итак, я попытался использовать переменную $indir в операторе for ($indir$f instead of $f), но это не сработало. Если я echo $f, то я могу видеть все файлы в каталоге, но скрипт просто ничего не сделает.

Короче говоря, я хочу использовать getopts для указания входного каталога, содержащего файлы для редактирования, и выходного каталога для сохранения отредактированных файлов.

Мысли?


person Fetch    schedule 23.04.2016    source источник
comment
indir="$OPTARG" ; cd "$indir" ; .... ? ИЛИ лучше добавить код / между каталогом и файлом, то есть tr -cd "[:print:]\n" < $indir/$f? То же самое для $outdir/$f. Удачи.   -  person shellter    schedule 23.04.2016


Ответы (1)


Я считаю, что проблема в этом:

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

Если f включает путь, то вы обрезаете весь путь, а не только имя файла, так что это никогда не будет правдой:

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

Вот исправление, начиная с 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)
person webb    schedule 23.04.2016
comment
Где бы вы предложили лучшее место, чтобы вставить это? Вместо for f in *.log или до и подмножество for f ? Я сейчас не на машине, на которой у меня есть мой скрипт, поэтому я не могу проверить его, чтобы проверить. Я дам вам знать завтра. Что касается awk, я просто небрежно добавил это, потому что знаю, что проблема не в awk. Это не тот awk, который я использую :) - person Fetch; 25.04.2016
comment
уточнил куда ставить :) - person webb; 25.04.2016
comment
Работал отлично! Спасибо за помощь мой друг! - person Fetch; 26.04.2016