Другое решение состоит в том, чтобы разобрать журнал:
function consume(pat) {
sub(/^[ \t]+/, "") # strip leading whitespace
if (!match($0, pat)) return
s = substr($0, p, RLENGTH) # extract part matching regex pattern
$0 = substr($0, RSTART + RLENGTH + 1) # strip matched part
return s
}
BEGIN {
# regular expressions to match ...
nonblank = "[^ \t]+" # a sequence of non-whitespace characters
quoted_string = "\"[^\"]+\"" # a ""-quoted string
bracketed_string = "\\[[^]]+\\]" # a []-quoted string
}
{ print
array["ip"] = consume(nonblank)
array["identity"] = consume(nonblank)
array["userid"] = consume(nonblank)
array["time"] = consume(bracketed_string)
array["request"] = consume(quoted_string)
array["status"] = consume(nonblank)
array["size"] = consume(nonblank)
array["referer"] = consume(quoted_string)
array["agent"] = consume(quoted_string)
for (key in array) printf " %10s: %s\n", key, array[key]
}
Обратите внимание, что встроенные кавычки скинут парсер. Есть и другие улучшения, но я надеюсь, что вы поняли идею.
Тем не менее, я думаю, что если вам нужно больше энергии, лучше проверить специализированные парсеры лог-файлов или более мощный язык сценариев. Например, в Perl есть модуль Text::Balanced, который может извлекать строки в кавычках и в скобках, и, как правило, выполняет The Right Thing со встроенными кавычками и другими трудностями. (Кстати, скрипт на Perl с использованием Text::Balanced будет выглядеть очень похоже на выше!)