如何处理从最旧到最新的bash文件?
概述 我有一堆日志文件,当它们达到一定大小时会滚动。日志文件中的每一行都有一组记录器格式,然后是一些有趣的信息。我想将这些文件从每一行的开头删除格式,然后将所有这些文件的输出放在一个文件中。然后,我最终会将该文件手动加载到另一个应用程序中 详细信息 文件结构如下所示:如何处理从最旧到最新的bash文件?,bash,sed,Bash,Sed,概述 我有一堆日志文件,当它们达到一定大小时会滚动。日志文件中的每一行都有一组记录器格式,然后是一些有趣的信息。我想将这些文件从每一行的开头删除格式,然后将所有这些文件的输出放在一个文件中。然后,我最终会将该文件手动加载到另一个应用程序中 详细信息 文件结构如下所示: logs |-- modules | +-- ... |-- application.log |-- gc.log |-- gc.log.1 |-- ... +-- gc.log.10 因此,日志包含子目录和
logs
|-- modules
| +-- ...
|-- application.log
|-- gc.log
|-- gc.log.1
|-- ...
+-- gc.log.10
因此,日志
包含子目录和多个日志文件。我安装的是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
来获取文件。我在另一个SO问题上发现了这一点(对不起,我忘了是哪一个)
我使用以下方法列出文件,然后将其从最旧到最新排序:
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
获取输出,然后将所有内容连接到一个文件中
问题
最后一个问题是:
- 我怎样才能在一个目录中以反自然数排序顺序列出某些文件,从这些文件中每行的开头删除一个模式,最后将结果连接到一个文件中(在bash中)
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 ...
在这种情况下,您的文件名非常简单,而您对它们所做的工作却很少,我很想使用ls输出,假设您的文件具有直观的渐进式修改时间,那么您只需要:
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]
如果您想正确操作(并让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)
而IFS=read-r-d''mtime&&IFS=read-r-d''文件名;做
sed-e的//^.{7\}[|].{10\}[|].{21\}[|]//g'您有GNU查找
?如果是这样的话,我们可以使用-printf
将修改时间放入输出中,假设这确实是您想要排序的。顺便说一句,写一篇文章而不是一个孤立的问题(或两个或三个问题)有点不理想。其他人希望能够在shell脚本中按mtime安全地对任意命名的文件进行排序的可能性非常非常高,因此,如果一个问题只问这个问题(如果这个主题上还没有),就会得到大量的视图/投票/答案。询问如何同时完成A、B和C,意味着你会得到一个答案只对你有用的问题,因为几乎没有人会有完全相同的文件格式&C。@EdMorton抱歉,这是一个复制粘贴错误。我在测试期间重命名了它们。我已经更新了问题。@charlesduff感谢您的反馈。我这样做只是因为我读了一些其他问题,每个人都想要实际的用例,而不是OP认为他们想要在一个人为的例子中做什么。这是一个平衡的行为,可以肯定。啊,我以前从未见过支架扩展。似乎它可以工作,但我遗漏的是,文件的数量是可配置的。默认情况下只有10个(最多9个版本),但情况可能并非总是如此。对于未来的读者,wrapper.log
=gc.log
(有一个复制粘贴错误已在问题中修复)。@EdMorton是的,我同意,对不起。我在测试时遇到了这个问题,因此我使用了sort-Vr
,但忘记了更新问题。我想我会使用类似的东西,因为它很容易理解。似乎不能处理空格,但现在还可以。虽然我目前正在使用我的find
方法,而不是ls
,并且它正在做这项工作(实际上时间戳可能还可以,但对于测试,我是按各种顺序创建的)。