【问题标题】:What should 'RS' be set to in this awk command在这个 awk 命令中应该将“RS”设置为什么
【发布时间】:2016-03-02 11:36:09
【问题描述】:

我正在使用 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 变量;我需要[]方括号之间的完整内容,所以我尝试将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 仍然是换行符。

【问题讨论】:

  • tks 为您提供建议:D
  • tnx 接受建议 ;-) 很高兴你得到了解决方案。祝大家好运。

标签: linux awk


【解决方案1】:

更新:再想一想,您可以使用 单个 输入字段分隔符正则表达式(通过选项 -F 指定,转换为变量 FS ):

awk -F ',\\[?|\\]' '{ print $2 ,$3, $6 ,$7 }' removed-apply.log.2016-02-19

注意需要 double \ 实例以在 regex的上下文中将它们后面的字符作为 literal 生成>。例如,\\[ 通过 awk 的初始 string 解析转换为文字 \[,然后 regex 解析将其视为 \[,导致解释为文字 [。简而言之:string ,\\[?|\\] 导致 regex ,\[?|\]


原始答案(已接受):

您的输入仍然明显面向行,因此没有理由更改输入记录分隔符RS

相反,在两个步骤中解析每一行:

  • 使用FS最初将输入分成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

【讨论】:

  • 方括号“[]”是一个字符类,所以“[][]”意味着[或]可以匹配......直到我查看常规时我才弄明白表达语法...谢谢您的回复!它救了我~:D
  • @JasonHuang:是的,[][] 看起来很奇怪;很高兴你想出来了。还要注意我添加的更简单的解决方案。
【解决方案2】:

使用“]”作为 RS 似乎是朝错误方向迈出的一步。 (您如何区分由“[abc]”组成的输入文件和由“[abc”组成的输入文件?)

假设您想要的文本在同一行的方括号之间,以下将能够处理您描述的输入类型:

grep '\[.*\]' | sed -e 's/^[^[]*\[\(.*\)\].*/\1/'

您可能需要根据您的需求细节进行调整。将其转换为 awk 也很容易。

如果您的要求比上述要求更复杂,请详细说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    相关资源
    最近更新 更多