我正在使用awk从日志文件中去除有用的信息。 这是我的日志文件看起来像:
2016-02-19 20:18:46,861 115971,100126017,524,523,1,[144115198332971054] 2016-02-19 20:18:46,874 95496,100126019,5,5,0,[] 2016-02-19 20:18:46,883 115974,100126025,57,57,0,[] 2016-02-19 20:18:46,891 115975,100126026,4,4,0,[] 2016-02-19 20:18:46,918 115976,100126027,122,122,0,[] 2016-02-19 20:18:47,688 115978,100126029,11656,11641,15,[144115198334490817,144115197319238988,144115197291063350,144115198332904743,144115197318718547,144115197319714394,144115197306930902,144115197250548791,144115198320676757,14411519 7253880518,144115197289305237,144115198083289344,144115197319697491,144115198273784435,144115198081583082] 2016-02-19 20:18:47,731 99590,100126032,12,12,0,[] 2016-02-19 20:18:47,832 115982,100126034,1397,1396,1,[144115198273784435] 2016-02-19 20:18:47,849 106705,100126035,31,31,0,[] 2016-02-19 20:18:47,860 107469,100126036,16,16,0,[] 2016-02-19 20:18:47,927 115983,100126037,824,824,0,[] 2016-02-19 20:18:47,985 115985,100126039,564,564,0,[] 2016-02-19 20:18:48,048 115986,100126040,338,338,0,[] 2016-02-19 20:18:48,108 115987,100126041,259,259,0,[] 2016-02-19 20:18:48,187 115989,100126043,693,692,1,[144115198273784435]
我使用","
作为FS
variables; 我需要在[]
方括号之间的完整内容,所以我试图把RS
设置为"]"
:
awk 'BEGIN { FS=","; RS="]";} { print $2 ,$3, $6 ,$7}' removed-apply.log.2016-02-19
但结果是错误的:
861 115971 100126017 1 [144115198332971054] 874 95496 100126019 0 [] 883 115974 100126025 0 [] 891 115975 100126026 0 [] 918 115976 100126027 0 [] 688 115978 100126029 15 [144115198334490817 731 99590 100126032 0 [] 832 115982 100126034 1 [144115198273784435] 849 106705 100126035 0 [] 860 107469 100126036 0 [] 927 115983 100126037 0 [] 985 115985 100126039 0 [] 048 115986 100126040 0 [] 108 115987 100126041 0 [] 187 115989 100126043 1 [144115198273784435]
似乎RS
仍然是断线。
更新 :第二个想法,你可以逃脱一个单一的输入字段分隔符正则表达式(通过选项-F
,这意味着变量FS
)指定:
awk -F ',\\[?|\\]' '{ print $2 ,$3, $6 ,$7 }' removed-apply.log.2016-02-19
请注意,需要双倍 \
实例来产生在正则表达式的上下文中作为文字的字符。 例如, \\[
通过awk
的初始字符串解析转换成文字\[
, 正则表达式解析然后被视为\[
,导致解释为文字 [
。 简而言之: 字符串 ,\\[?|\\]
产生正则表达式 ,\[?|\]
。
原始答案 (如接受):
你的输入仍然是明确的面向行的 ,所以没有理由改变输入记录分隔符RS
。
相反,分两步来解析每一行:
FS
将输入初始化为2个字段:before [
, [...]
之间和[...]
之间。
[][]
是包含2个文字字符的字符集( [...]
), ]
和[
它在概念上等同于\[|\]
。 split()
将每个结果字段拆分成存储在数组中的子字段: awk ' BEGIN { FS="[][]" } # split into $1 (before "[") and $2 (between "[...]") { split($1, fa1, ",") # split $1 into subfields by "," and store in array fa1 split($2, fa2, ",") # split $2 into subfields by "," and store in array fa2 # Output fields of interest print fa1[2], fa1[3], fa2[1], fa2[2] }' removed-apply.log.2016-02-19
使用“]”作为RS似乎是朝着错误的方向迈出的一步。 (你怎么知道由“[abc]”组成的输入文件与由“[abc]?”组成的输入文件之间的区别?
假设你想要的文本位于同一行的方括号之间,以下代码将能够处理你描述的输入类型:
grep '\[.*\]' | sed -e 's/^[^[]*\[\(.*\)\].*/\1/'
您可能需要调整这取决于您的要求的细节。 把它翻译成awk也很容易。
如果你的要求比上面的要复杂得多,那么请详细说明一下。