awk/sed 修改log中的时间戳
Posted lvmxh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了awk/sed 修改log中的时间戳相关的知识,希望对你有一定的参考价值。
1. use awk
https://stackoverflow.com/questions/2371248/how-to-convert-timestamps-to-dates-in-bash
https://www.oreilly.com/library/view/learning-awk-programming
echo "1685182062 b4:96:91:e7:b5:5a 192.168.1.207 ubuntu-f9d679eb0e ff:38:fe:2f:82:00:02:00:00:ab:11:ea:3a:b2:bd:b0:46:dd:8e" | \\
awk \' printf strftime("%c: ", $1); $1 = ""; print $0; \'
echo "1685182062 b4:96:91:e7:b5:5a 192.168.1.207 ubuntu-f9d679eb0e ff:38:fe:2f:82:00:02:00:00:ab:11:ea:3a:b2:bd:b0:46:dd:8e" | \\
awk \' format = "%d-%m-%Y/%H:%M:%S"; printf strftime(format, $1); $1 = ""; print $0; \'
echo "1685182062 b4:96:91:e7:b5:5a 192.168.1.207 ubuntu-f9d679eb0e ff:38:fe:2f:82:00:02:00:00:ab:11:ea:3a:b2:bd:b0:46:dd:8e" | \\
awk -F"," \'OFS=","; $1=strftime("%Y-%m-%d %H:%M:%S", $1); print\'
echo "1685182062 b4:96:91:e7:b5:5a 192.168.1.207 ubuntu-f9d679eb0e ff:38:fe:2f:82:00:02:00:00:ab:11:ea:3a:b2:bd:b0:46:dd:8e" | \\
awk \'$1=strftime("%c", $1); print\'
2. use sed
https://unix.stackexchange.com/questions/168315/how-can-i-convert-timestamps-in-a-column-to-a-date
echo "1685182062 b4:96:91:e7:b5:5a 192.168.1.207 ubuntu-f9d679eb0e ff:38:fe:2f:82:00:02:00:00:ab:11:ea:3a:b2:bd:b0:46:dd:8e" | \\
sed \'s/^/echo "/; s/\\([0-9]\\10\\\\)/`date +"%Y-%m-%d\\/%H:%M:%S" -d @\\1`/; s/$/"/\' | bash
REF:
shell convert timestamp to date format
shell log line convert timestamp to date
shell log convert timestamp to date
awk 高级用法
awk modify one field with shell command
如何使用 shell(awk、sed 等)删除文件中的前两列
【中文标题】如何使用 shell(awk、sed 等)删除文件中的前两列【英文标题】:how to remove the first two columns in a file using shell (awk, sed, whatever) 【发布时间】:2012-11-06 22:18:28 【问题描述】:我有一个包含很多行的文件 在每一行中有许多列(字段),由空格“”分隔 每行的列数不同 我想删除前两列 怎么做?
【问题讨论】:
Using awk to print all columns from the nth to the last的可能重复 【参考方案1】:使用 awk,并基于下面的一些选项,使用 for 循环会更灵活一些;有时我可能想删除前 9 列(例如,如果我执行“ls -lrt”),所以我将 2 更改为 9,就是这样:
awk ' for(i=0;i++<2;)$i=""; print $0 ' your_file.txt
【讨论】:
【参考方案2】:使用kscript
kscript 'lines.split().select(-1,-2).print()' file
【讨论】:
【参考方案3】:只用 shell 很简单
while read A B C; do
echo "$C"
done < oldfile >newfile
【讨论】:
这是一个很好的答案,但是您需要使用read -r
而不是 read
。
read -r
将保留反斜杠。 read
不会。例如:echo "foo ba\r"
将产生foo ba\r
的输出。但是,echo "foo ba\r" | (while read first_column second_column; do echo "$second_column"; done)
将仅生成bar
作为输出(删除了反斜杠。添加-r
标志会生成ba\r
的正确输出【参考方案4】:
perl:
perl -lane 'print join(' ',@F[2..$#F])' File
awk:
awk '$1=$2=""1' File
【讨论】:
【参考方案5】:您可以使用cut
:
cut -d " " -f 3- input_filename > output_filename
说明:
cut
:调用剪切命令
-d " "
:使用单个空格作为分隔符(cut
默认使用 TAB)
-f
:指定要保留的字段
3-
: 以字段 3 开头的所有字段
input_filename
:使用这个文件作为输入
> output_filename
:将输出写入此文件。
或者,您可以使用awk
:
awk '$1=""; $2=""; sub(" ", " "); print' input_filename > output_filename
说明:
awk
:调用 awk 命令
$1=""; $2="";
:将字段 1 和 2 设置为空字符串
sub(...);
:清理输出字段,因为字段 1 和 2 仍将由“”分隔
print
: 打印修改后的行
input_filename > output_filename
:同上。
【讨论】:
@wenzi 哎呀,忘了cut
默认使用制表符作为分隔符。查看更新的答案 - 刚刚经过测试,它可以工作。在其他条件相同的情况下,我建议使用 cut
而不是 awk
。
您可以在 awk 中使用 awk 'sub(/([^ ]+ )2/, "")1'
。我同意如果你有一个单字符字段分隔符,无论如何 cut 是更好的选择。
还有一些空格,请改用awk '$1=""; $2=""; sub(/^ +/, ""); print'
或更短的awk '$1=$2=""; sub(/^ +/, "")1'
【参考方案6】:
感谢您发布问题。我还想添加对我有帮助的脚本。
awk ' $1=""; print $0 ' file
【讨论】:
Awk 在这种情况下不保留字段分隔符。 可以加OFS=FS
保留分隔符:unix.stackexchange.com/a/252748/112834【参考方案7】:
这是一种相对容易理解的使用 Awk 的方法:
awk 'print substr($0, index($0, $3))'
这是一个没有模式的简单 awk 命令,因此 内的操作针对每个输入行运行。
操作是简单地打印从第三个字段的位置开始的子字符串。
$0
: 整个输入行
$3
: 第三场
index(in, find)
:返回find
在字符串in
中的位置
substr(string, start)
:返回从索引 start
开始的子字符串
如果您想使用不同的分隔符,例如逗号,可以使用 -F 选项指定:
awk -F"," 'print substr($0, index($0, $3))'
您还可以通过在 中的操作之前指定模式来对输入行的子集进行操作。只有与模式匹配的行才会运行操作。
awk 'patternprint substr($0, index($0, $3))'
模式可以是这样的:
/abcdef/
:使用正则表达式,默认对$0进行操作。
$1 ~ /abcdef/
:对特定字段进行操作。
$1 == blabla
:使用字符串比较
NR > 1
:使用记录/行号
NF > 0
:使用字段/列号
【讨论】:
谢谢你,这是一个比 IMO 接受的更好的答案 去掉最后两列怎么样,倒数? 如果字段 #2 和字段 #3 的内容相同,这将无法正常工作。【参考方案8】:这可能对你有用(GNU sed):
sed -r 's/^([^ ]+ )2//' file
或者对于由一个或多个空格分隔的列:
sed -r 's/^(\S+\s+)2//' file
【讨论】:
【参考方案9】:你可以使用sed
:
sed 's/^[^ ][^ ]* [^ ][^ ]* //'
这会查找以一个或多个非空白、一个空白、另一组一个或多个非空白和另一个空白开头的行,并删除匹配的材料,即前两个字段。 [^ ][^ ]*
比等效但更明确的 [^ ]\1,\
符号略短,第二个可能会遇到 GNU sed
的问题(尽管如果您使用 --posix
作为选项,即使 GNU sed
也不能搞砸了)。 OTOH,如果要重复的字符类更复杂,则编号符号会为简洁起见。很容易将其扩展为处理“空白或制表符”作为分隔符,或“多个空白”或“多个空白或制表符”。也可以对其进行修改以处理第一个字段之前的可选前导空格(或制表符)等。
对于awk
和cut
,请参阅Sampson-Chen 的answer。还有其他方法可以编写awk
脚本,但它们并不比给出的答案更好。请注意,如果您不希望将制表符视为分隔符,或者字段之间可能有多个空格,则可能需要在 awk
中显式设置字段分隔符 (-F" "
)。 POSIX 标准cut
不支持字段之间的多个分隔符; GNU cut
具有有用但非标准的 -i
选项,允许在字段之间使用多个分隔符。
你也可以在纯shell中做:
while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
【讨论】:
如果residue
可以包含反斜杠,上面的读取将解释它,而不是在输出中重现它。始终使用while IFS= read -r ...
。
如果bash
用普通的read
解释内容,那么bash
被破坏(再次)。原始 shell 中的 read 命令没有做这种废话;我不相信 POSIX shell 需要它。如果发现bash
做了你所说的那样,我会很生气——我已经对这个程序产生了爱/恨的关系,因为它在很多事情上都做得很好,但也有一些事情做得很糟糕,并且改变遗留行为是最糟糕的行为之一,并且需要启用旧标准行为的选项是......非常烦人。看来你是对的; bash
很无聊!
这种行为是 POSIX,参见 pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html。
我明白了,我没有明确说出来,但您需要 IFS= 的原因是,如果输入中的第一个字段为空,则默认字段拆分将去除前导空格,因此 residue
将开始在字段 4(或更高版本)而不是字段 3。
该死的...好的; POSIX 很糟糕,但 bash
正在追随 POSIX 2008。在超过 25 年的 shell 编程中,我从来没有想要这个功能,但我想我一定是少数。以上是关于awk/sed 修改log中的时间戳的主要内容,如果未能解决你的问题,请参考以下文章