我想根据用户的输入(例如:1218738496)根据第8列过滤一个充满日志文件的目录,并输出到文本文件。我有一个有效的解决方案,但我正在寻找一个更好的解决方案,提供更好的性能,因为总文件大小可能超过1GB +。
问题1: 某些行格式不一致。
问题2: 如果第8行与输入匹配,则它下面的行(不包含INSERT)也应该输出到文件。
示例数据
ACTION,INSTALLATION_ID,LOG_TIMESTAMP_SECONDS,LOG_TIMESTAMP_FRACTIONS,LOG_TIMESTAMP,THREAD_ID,SEQUENCE_NUMBER,LOG_LEVEL_TYPE
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1127192896,0,DEBUG3
0010: 69 6c 65 40 10 92 0f 0e 67 b9 72 aa 5d e1 03 63
]",,default,false
INSERT,SLT_TEST_1,2015/06/02 14:07:13.305 (Asia/Colombo),1127192896,1,DEBUG1
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,14,DEBUG3
<v s=""MONTHLY_PEAK_DWNLOAD""/>
</a><a n=""thresholdScheme""><o t=""PM_UsageMonitorConfigThreshold"">
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,15,DEBUG3
0010: 69 6c 65 40 10 92 0f 0e 67 b9 72 aa 5d e1 03 63
]",,default,false
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,17,DEBUG3
期望的输出
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,14,DEBUG3
<v s=""MONTHLY_PEAK_DWNLOAD""/>
</a><a n=""thresholdScheme""><o t=""PM_UsageMonitorConfigThreshold"">
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,15,DEBUG3
0010: 69 6c 65 40 10 92 0f 0e 67 b9 72 aa 5d e1 03 63
]",,default,false
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,17,DEBUG3
我目前的工作脚本
for file in $(ls -rt $directory)
do
echo "Reading file : " $file
# || [[ -n "$line" ]] <-- prevent last line being ignored if doesn't end with newline
while IFS= read -r line || [[ -n "$line" ]]
do
# if line contains INSERT
if [[ $line == *"INSERT"* ]]
then
# Break it to access the thread ID
breakdown=(${line//,/ })
threadID=${breakdown[4]}
if [[ $threadID == "$inputThreadID" ]]
then
seqID=${breakdown[5]}
echo $line >> ./output_unsorted.txt
fi
else
# The "too long lines" check if they belong to the ID log we want
if [ "$threadID" == "$inputThreadID" ] && [[ $line != *"ACTION,INSTALLATION_ID"* ]]
then
if [ "$lastSeqID" != "$seqID" ]
then
echo $line >> ./output_unsorted.txt
else
echo $line >> ./output_unsorted.txt
fi
fi
fi
done < "$directory/$file"
done
答案 0 :(得分:2)
这会产生您要求的输出:
$ awk -F, '/INSERT/{f=0} $4==1218738496{f=1} f' file
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,14,DEBUG3
<v s=""MONTHLY_PEAK_DWNLOAD""/>
</a><a n=""thresholdScheme""><o t=""PM_UsageMonitorConfigThreshold"">
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,15,DEBUG3
0010: 69 6c 65 40 10 92 0f 0e 67 b9 72 aa 5d e1 03 63
]",,default,false
INSERT,SLT_TEST_1,2015/06/02 14:07:26.860 (Asia/Colombo),1218738496,17,DEBUG3
工作原理:
-F,
将输入字段分隔符设置为逗号。
/INSERT/{f=0}
如果该行包含INSERT
,我们会将标记f
设置为零(false)。
$4==1218738496{f=1}
如果第四个字段是您选择的号码,那么我们将标志f
设置为一个(真)。
f
如果f
为真,请打印该行。
这使用非常相似的逻辑并产生相同的输出,但使用bash:
#!/bin/bash
f=
while IFS= read line
do
[[ $line == *"INSERT"* ]] && f=
IFS=, read a b c d rest <<<"$line"
[ "$d" = 1218738496 ] && f=1
[ "$f" ] && echo "$line"
done <file