我有包含数据行的日志:
Mon Apr 20 03:15:18 EDT 2015: my|data|data|data
我正在尝试编写一个脚本,该脚本仅从日志中提取数据,并去除前导时间戳:
while read p
do
echo $p | sed "s/.* EDT $year: //g" > replay_message_$count.txt;
count=$((count+1));
done < $fileName
现在我正在使用模式.* EDT $year:
,其中$year
是用户传递的参数。
无需传递年份作为参数即可提取数据的方法是什么?
答案1
如果您知道日期格式始终有六个空格分隔的字段,则可以使用:
cut -d ' ' -f 7-
如果您知道您的时间戳始终占用 30 个字符,则可以使用:
cut -c 31-
如果您知道时间戳以数字结尾,后跟冒号,后跟空格,并且您的数据不包含此模式,则可以使用:
sed 's/.*[0-9]: //'
如果您有更具体的要求,欢迎您提出。
答案2
这是为了替换while
脚本中的所有循环:
awk '{print substr($0, 31)>("replay_message_" NR-1 ".txt")}' file
怎么运行的:
print substr($0, 31)
这将打印该行除前三十个字符之外的所有字符。
>("replay_message_" NR-1 ".txt")
这会将打印的内容发送到以行号命名的文件中。
当 awk 命令运行完成后,您的目录中将出现一系列文件,例如:
$ ls -1 replay_message*
replay_message_0.txt
replay_message_1.txt
replay_message_2.txt
replay_message_3.txt
时间戳长度变化的替代方案
awk '{sub(/.* E[SD]T [[:digit:]]{4}: /, ""); print >("replay_message_" count++ ".txt")}' file
怎么运行的
awk 一次隐式读取一个文件的一条记录(行)。对于每行:
sub(/.* EDT [[:digit:]]{4}: /, "")
这会从行的开头删除时间戳。
正则表达式匹配所有内容,包括空格、时区(EST 或 EDT)、空格、年份的四位数字、冒号和空格。
或者,如果保证您的时间戳仅需要 30 个字符,则可以使用更简单的替换:
sub(/.{30}/, "")
根据您的输入文件,您必须决定最适合您的情况。
print >("replay_message_" count++ ".txt")
这会将修改后的行写入包含数字的文件中
count
。这++
会导致count
随每次写入而递增。