Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 将包含多行记录的日志文件中的数据提取到CSV_Linux_Database_Parsing_Csv - Fatal编程技术网

Linux 将包含多行记录的日志文件中的数据提取到CSV

Linux 将包含多行记录的日志文件中的数据提取到CSV,linux,database,parsing,csv,Linux,Database,Parsing,Csv,我有一个搜索算法,可以解析日志文件,并将结果放入以下格式: [Mon May 2 13:46:00 2016]Local/ESSBASE///139969058175296/Info(4052237) Logging out user [accelatisro@Native Directory], active for 0 minutes -- [Mon May 2 13:46:00 2016]Local/ESSBASE///139969068702016/Info(4052237) Log

我有一个搜索算法,可以解析日志文件,并将结果放入以下格式:

[Mon May  2 13:46:00 2016]Local/ESSBASE///139969058175296/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 0 minutes
--
[Mon May  2 13:46:00 2016]Local/ESSBASE///139969068702016/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 4 minutes
--
[Mon May  2 13:46:01 2016]Local/ESSBASE///139969078176064/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 6 minutes
--
[Mon May  2 13:46:01 2016]Local/ESSBASE///69062385984/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 45 minutes
--
[Mon May  2 13:46:01 2016]Local/ESSBASE///69160071488/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 3 minutes
--
[Mon May  2 13:46:02 2016]Local/ESSBASE///969053964608/Info(4052237)
Logging out user [accelatisro@Native Directory], active for 3 minutes
我需要获取注销用户的日期(即:5-2-2016 13:46:02)(即:accelatisro@Native目录),以及它们的活动时间(即:45分钟)。然后我需要将结果写入逗号分隔的格式,以便将信息上载到数据库(即:5-2-2016 13:46:02,accelatisro@Native目录,45)。这个文件大约有45000行长,所以手工操作是不行的


对于这个问题,我应该采取什么方法?

简单的方法是为可能需要匹配的每一行编写一个正则表达式,然后遍历文件,从每个匹配的行中填充数据,并在看到记录分隔符时发出该数据。例如:

#!/bin/bash

l1_re='^\[([^\]+)]'
l2_re='Logging out user \[([^\]+)], active for ([[:digit:]]+) minutes'
delim='--'

flush() {
  [[ $time && $user && $minutes ]] || return
  printf '%s,%s,%s\n' "${time//,/}" "${user//,/}" "${minutes//,/}"
  time=; user=; minutes=
}

while IFS= read -r line; do
  if [[ $line =~ $l1_re ]]; then
    time=${BASH_REMATCH[1]}
  elif [[ $line =~ $l2_re ]]; then
    user=${BASH_REMATCH[1]}
    minutes=${BASH_REMATCH[2]}
  elif [[ $line = $delim ]]; then
    flush
  fi
done
flush
根据您给定的输入,这将发出:

Mon May  2 13:46:00 2016,accelatisro@Native Directory,0
Mon May  2 13:46:00 2016,accelatisro@Native Directory,4
Mon May  2 13:46:01 2016,accelatisro@Native Directory,6
Mon May  2 13:46:01 2016,accelatisro@Native Directory,45
Mon May  2 13:46:01 2016,accelatisro@Native Directory,3
Mon May  2 13:46:02 2016,accelatisro@Native Directory,3

“请为我写这个程序”的问题在这里不受欢迎。具体地说,它们太宽泛了——不局限于一个特定的技术问题。这里面可能隐藏着一个允许的问题。看看我能不能编辑一下,把它拉出来。是的,好吧,如果你对这个问题的理解更好,那该怎么办呢。顺便说一句,关于社区规范的讨论,请参见。我们确实不赞成那些不能表明你自己已经努力找出解决方案的问题。有几个问题:这个项目是如何接受意见的?当IFS=read-r行时,
-r
中表示什么;do
do?@Michael,
read
从stdin中读取一行,因此您可以运行
/convert out.csv
。背景见BashFAQ#1 at。@Michael,
-r
使bashslashes被逐字解释——没有它,它们部分地被处理为转义字符,因此
\\foo
将变成
\foo
(作为一个例子)。