Это решение использует сценарий awk для преобразования дат в первом файле в количество секунд с начала эпохи и добавляет это число перед выводом. Мы используем date +% s --date
для выполнения тяжелой работы и записываем вывод команды в переменную awk secs
, вызывая функцию awk getline
. (Синтаксис awk: команда | getline
переменная ).
awk <log1 >log1.new '
{ y = substr($0,3,4); m = $2; d = $3; hms = substr($0,15,8)
"date \"+%s\" --date \"" d " " m " " y " " hms "\"" | getline secs
print secs " " $0
}'
Второй сценарий awk делает то же самое для второго файла, но только для первой строки с меткой времени, которая сохраняется в переменной awk base
. В других строках мы просто добавляем смещение минут и секунд к этой базе и используем date
для преобразования секунд, прошедших с эпохи, в настоящую дату в формате первого файла.
awk <log2 >log2.new '
/^Timestamp/{ split($5,x,":"); dmy = sprintf("%04d/%02d/%02d",x[3],x[2],x[1])
split($3,x,":"); hms = sprintf("%02d:%02d:%02d",x[1],x[2],x[3])
"date \"+%s\" --date \"" dmy " " hms "\"" | getline base
}
/^\[/ { mins = substr($0,2,2); secs = substr($0,5,2);
tot = base + mins*60+secs
"date \"+%Y %b %d %H:%M:%S\" --date @" tot | getline date
print tot " -:" date " " substr($0,8)
}'
Затем два файла объединяются путем сортировки по числовому полю , и, наконец, число удаляется с помощью sed.
sort -m -n -k1,1 log1.new log2.new |
sed 's/^[^ ]* //'
Утилита getopts
не знает об обязательных опциях, только о том, какие опции разрешены (и какие из них должны принимать аргумент опции ). Если вы хотите применить обязательные параметры, вам придется сделать это с помощью собственных тестов в цикле разбора параметров или после него.
Утилита getopts
не делает этого, потому что параметры могут иметь более сложные взаимосвязи, например, некоторые параметры конфликтуют, некоторые параметры требуют наличия других параметров и т. д. Это остается на усмотрение автора сценария с помощью собственной логики..
Я не совсем уверен, о чем вы спрашиваете, но что делает getopts
, так это то, что он анализирует командную строку, которая уже была передана программе, и выводит варианты, которые он видит, один -на -один, в формате, который довольно легко обрабатывается программным кодом. У него есть возможность печатать ошибки для параметров, которые ему неизвестны, но это все, что он делает.
На самом деле он ни у кого ничего не "спрашивает", так как командная строка уже исправлена при вызове getopts
. Нет никакого взаимодействия, если остальная часть программы не реализует его.
Он также не знает и не может знать, какие параметры необходимы для работы программы. (для этого нет синтаксиса в "optstring" getopts
, принимаемом в качестве аргумента ). Обычный случай состоит в том, что никакие параметры не требуются (подумайте ls
, rm
, vi
... ), а в тех случаях, когда у вас есть необходимые параметры, вы можете проверьте их вручную в скрипте.
Рассмотрим этот пример:
#!/bin/bash
opt_a=
opt_b=
while getopts 'a:bc' opt; do
case $opt in
a) opt_a=$OPTARG;;
b) opt_b=1;;
esac
done
if [ -z "$opt_a" ]; then
echo "option a was NOT given, exit."
exit 1;
fi
echo "do something with a='$opt_a' b=$opt_b"
Сценарий явно проверяет, было ли задано значение a
. Без проверки программа с удовольствием продолжила бы работу и без нее. getopts
также предлагается принять c
в качестве опции, и для этого не выдается ошибка. Скрипт просто полностью его игнорирует, так как я не поместил туда случай c)
или *)
. getopts
не может знать, что этот конкретный параметр будет проигнорирован.
Обратите внимание, что обычно квадратные скобки в подсказке об использовании означают, что параметр является необязательным, поэтому, если вы имеете в виду, что все -w
, -o
, -c
, -t
должны быть предоставлены вашему сценарий, я бы предложил снять скобки.