在这个awk命令中应该设置什么“RS”

我正在使用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] 

我使用","作为FSvariables; 我需要在[]方括号之间的完整内容,所以我试图把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也很容易。

如果你的要求比上面的要复杂得多,那么请详细说明一下。