【发布时间】:2021-10-24 11:29:00
【问题描述】:
我有一些大型日志文件具有来自 RFC3162 (MMM dd HH:mm:ss) 的旧 syslog 格式日期,我想将其更改为来自 RFC5424 (YYYY-mm-ddTHH:mm:ss) 的新 syslog 格式日期+TMZ)。我创建了以下 bash 脚本:
#!/bin/bash
#Loop over directories
for i in $1
do
echo "Processing directory $i"
if [ -d $i ]
then
cd $i
#Loop over log files inside the directory
for j in *.2021
do
echo "Processing file $j"
#Read line by line and perform transformation on dates and append to new file
cat $j | \
while read CMD; do
tmpdate=$(printf '%s\n' "$CMD" | awk -F" $i" 'BEGIN {ORS=""}; {print $1}')
newdate=$(date +'%Y-%m-%dT%H:%M:%S+02:00' -d "$tmpdate")
printf '%s\n' "$CMD" | sed 's/'"$tmpdate"'/'"$newdate"'/g' >> $j.new
done
mv $j.new $j
done
cd ..
fi
done
但这需要很长时间才能执行,因为我有几百万行的文件(例如,邮件服务器上的日志可以追溯到一年多)。到目前为止,这已经运行了好几天,还有很多行要解析:-)
那么两个问题。
- 为什么这个脚本需要这么长时间才能执行?
- 有更快的方法吗?使用 GNU utils(sed、awk 等)、bash 或 python 之一。
======== 编辑 =======
以下是旧格式的示例:
Feb 1 21:59:44 calendar os-prober: debug: running /usr/lib/os-probes/50mounted-tests on /dev/sda2
Feb 1 21:59:44 calendar 50mounted-tests: debug: /dev/sda2 type not recognised; skipping
Feb 1 21:59:44 calendar os-prober: debug: os detected by /usr/lib/os-probes/50mounted-tests
注意2月和1日之间有2个空格,如果日期是10或更高,则空格只有1个
Feb 10 10:39:53 calendar os-prober: debug: running /usr/lib/os-probes/50mounted-tests on /dev/sda2
在新格式中,它看起来像这样:
2021-02-01T21:59:44+02:00 calendar os-prober: debug: running /usr/lib/os-probes/50mounted-tests on /dev/sda2
2021-02-01T21:59:44+02:00 calendar 50mounted-tests: debug: /dev/sda2 type not recognised; skipping
2021-02-01T21:59:44+02:00 calendar os-prober: debug: os detected by /usr/lib/os-probes/50mounted-tests
TIA。
【问题讨论】:
-
您可能想要
for i in "$@"而不是for i in $1- 根据定义,$1只能包含一个项目。 -
好吧,从技术上讲,未引用的
$1会进行分词和全局扩展,因此for i in $1会工作(或break,具体取决于您的查看)如果您致电script.sh "dir1 dir2 dir3"或script.sh "*"。是的,但是for i in "$@"; do或只是for i; do将是处理多个参数的明智方式。 -
啊,是的,那是
$1是因为我一次给脚本一个文件。由于 $things 的原因,我必须在笔记本电脑上执行此操作,并且解析一些文件需要很长时间,并且我需要在完成工作后关闭笔记本电脑的电源,然后我在尝试找出更好的方法时这样做了。