根据特定顺序在文件中的模式之后重新排列行

时间:2017-01-04 15:17:28

标签: linux shell unix awk sed

我有一个大型日志文件,格式如下

date pattern1
time pattern2
variable1_name val1
variable2_name val2
variable3_name val3
variable4_name val4
date pattern1
time pattern2
variable1_name val1
variable2_name val2
variable3_name val3
variable4_name val4

我创建了一个shell脚本,它以相同的顺序val1,val2,val3,val4

在数据库中插入这些值

问题是文件有时会被破坏,变量的顺序也不同,例如:

date pattern1
time pattern2
variable2_name val2
variable1_name val1
variable3_name val3
variable4_name val4
date pattern1
time pattern2
variable4_name val4
variable2_name val2
variable3_name val3
variable1_name val1

使用shell脚本,我想重新排列pattern1和pattern2之后的行,使其与原始日志文件的顺序相同。

3 个答案:

答案 0 :(得分:0)

据我所知,您需要使用变量排序块。

GNU sed的解决方案。

sed -r 's/^time pattern[0-9]*/&/; T; {p; N; N; N; N; s/^[^\n]*\n(.*)$/echo "\1" | sort/e}'

我们在这里找到time patternN(不是地址,所有这些都是)。如果我们找不到模式(替换不成功),我们会在T跳到脚本结尾。

接下来,我们打印(p)时间模式,阅读四行(N; N; N; N)并进行新的替换。

^[^\n]*\n是第一行时间模式。我们不需要它。

(.*)$是缓冲区,变量\1的其余部分。

我们将其替换为echo "\1" | sort。它是shell命令,将被执行,'我们/e的{​​{1}}修饰符。

s的输出将被传递到sort的主缓冲区,并在脚本执行结束时打印出来。

答案 1 :(得分:0)

这可能适合你(GNU sed):

sed '/^variable/{x;/./G;//!g;x;$!d};x;/./s/.*/echo "&"|sort/ep;z;x;/^variable/!p;d' file

如果行开始variable将其存储在保留空间(HS)中(如果HS已经有东西,请将其附加到该东西)。如果该行不以variable开头,请检查HS是否已经保留了某些内容以及是否对HS进行了排序,将其打印出来然后将其清除(准备下次)。如果该行不以variable开头(边缘情况:可能的最后一行输入)将其打印出来。

答案 2 :(得分:0)

如果变量名是不是的字母数字顺序(例如,如果variable1_name是"国籍",变量2_name是"高度",依此类推),那么原生排序功能不起作用。但这会:

sed '/pattern2/{N;N;N;N;P;h;s/.*\(variable1_name\)/\1/;P;g;s/.*\(variable2_name\)/\1/;P;g;s/.*\(variable3_name\)/\1/;P;g;s/.*\(variable4_name\)/\1/;P;d;}' filename