概述
我有一堆日志文件,当它们达到一定大小时会翻转。日志文件中的每一行都有一堆记录器格式,然后是一些有趣的信息。我想获取这些文件并从每行的开头删除格式,然后将所有这些文件的输出放入一个文件中。然后,我将最终获取该文件并手动将其加载到另一个应用程序中。
详情
文件结构如下所示:
logs
|-- modules
| +-- ...
|-- application.log
|-- gc.log
|-- gc.log.1
|-- ...
+-- gc.log.10
因此logs
包含子目录和多个日志文件。我感兴趣的是gc.log*
。
每个gc.log*
文件在文件填满时会翻转到新文件。 gc.log
始终是最新的,它最长为gc.log.10
是最早的(默认情况下只有10,最高版本9,但这是可配置的。)
典型的gc.log*
包含数千个条目,如:
INFO | jvm 1 | 2015/05/28 04:40:58 | 1164752.977: [GC pause (young), 0.06583700 secs]
INFO | jvm 1 | 2015/05/28 04:40:58 | [Parallel Time: 45.2 ms]
INFO | jvm 1 | 2015/05/28 04:40:58 | [GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
INFO | jvm 1 | 2015/05/28 04:40:58 | Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
...
(是的,这些是来自Oracle JVM的G1 GC日志。我需要在单独的文件中使用这些,以便我可以使用GCViewer绘图)
一旦我删除了格式化,我需要它看起来像:
1164752.977: [GC pause (young), 0.06583700 secs]
[Parallel Time: 45.2 ms]
[GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
到目前为止我有什么
到目前为止,我已经了解到我不应该使用ls
来获取文件。我在另一个问题上发现了这个问题(对不起,我忘了哪一个)Why you shouldn't parse the output of ls(1)。
我使用以下内容列出文件,然后将它们从最旧到最新排序:
find "$logDir" -maxdepth 1 -type f -name 'gc.log*' | sort -Vr
这给了我以下内容:
./gc.log.10
./gc.log.9
./gc.log.8
./gc.log.7
./gc.log.6
./gc.log.5
./gc.log.4
./gc.log.3
./gc.log.2
./gc.log.1
./gc.log
我必须删除格式的命令是:
sed -e 's/^.\{7\}[|].\{10\}[|].\{21\}[|] //g'
(我可以使用cut -c43-
)
问题
我不确定如何将sort
的输出转换为sed
。
当文件名(或$logDir
)包含空格时,以下操作无效:
find "$logDir" -maxdepth 1 -type f -name 'gc.log*' | sort -Vr | xargs sed -e "s/^.\{7\}[|].\{10\}[|].\{21\}[|] //g"
我还需要从sed
获取输出,然后将它们连接成一个文件。
问题
最后一个问题:
答案 0 :(得分:1)
由于你的文件名是固定的,你可以简单地使用大括号扩展:
for wrapper in wrapper.log{.{9..1},}; do
echo "$wrapper"
# do whatever you want to do...
done
出于您的目的,我想,这也可以起作用:
$ cat wrapper.log{.{9..1},} | sed ...
更通用的版本:
$ logfile="wrapper.log" # may contain spaces in filename
$ cat "$logfile"{.{9..1},} | sed ...
答案 1 :(得分:1)
在这种情况下,您的文件名非常简单,并且您对它们做的很少,我很想使用ls输出,假设您的文件具有直观的渐进式修改时间,那么所有的&# #39;需要的是:
ls -rt gc.? gc | xargs awk -F' [|] ' '{print $NF}' > newfile
例如:
$ cat gc
INFO | jvm 1 | 2015/05/28 04:40:58 | 1164752.977: [GC pause (young), 0.06583700 secs]
INFO | jvm 1 | 2015/05/28 04:40:58 | [Parallel Time: 45.2 ms]
INFO | jvm 1 | 2015/05/28 04:40:58 | [GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
INFO | jvm 1 | 2015/05/28 04:40:58 | Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
$
$ cat gc.1
INFO | jvm 1 | 2015/05/28 04:40:58 | 1234567.977: [GC pause (young), 0.06583700 secs]
INFO | jvm 1 | 2015/05/28 04:40:58 | [Parallel Time: 45.2 ms]
INFO | jvm 1 | 2015/05/28 04:40:58 | [GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
INFO | jvm 1 | 2015/05/28 04:40:58 | Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
$
$ cat gc.2
INFO | jvm 1 | 2015/05/28 04:40:58 | 8889996.977: [GC pause (young), 0.06583700 secs]
INFO | jvm 1 | 2015/05/28 04:40:58 | [Parallel Time: 45.2 ms]
INFO | jvm 1 | 2015/05/28 04:40:58 | [GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
INFO | jvm 1 | 2015/05/28 04:40:58 | Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
$ ls -rt gc.? gc | xargs awk -F' [|] ' '{print $NF}'
8889996.977: [GC pause (young), 0.06583700 secs]
[Parallel Time: 45.2 ms]
[GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
1234567.977: [GC pause (young), 0.06583700 secs]
[Parallel Time: 45.2 ms]
[GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
1164752.977: [GC pause (young), 0.06583700 secs]
[Parallel Time: 45.2 ms]
[GC Worker Start (ms): 1164752977.7 1164752977.7 1164752977.7 1164752977.9
Avg: 1164752977.8, Min: 1164752977.7, Max: 1164752977.9, Diff: 0.2]
答案 2 :(得分:1)
如果你想做得对(并且有GNU find
和sort
),请告诉find
写下以mtime开头的文件名,并用NUL字符分隔(唯一的字符是不能存在于UNIX上的文件的完全限定路径中;使用sort
按mtime排序(而不是试图弄乱名字);然后阅读以下两段数据:
while IFS= read -r -d ' ' mtime && IFS= read -r -d '' filename; do
sed -e 's/^.\{7\}[|].\{10\}[|].\{21\}[|] //g' <"$filename"
done < <(find "$logDir" -maxdepth 1 -type f -printf '%T@ %P\0' | sort -nz)
这将按照从最旧到最新的顺序处理文件。