正则表达式命令行更改每行的格式

时间:2016-01-18 13:29:46

标签: regex bash ubuntu sed gawk

我有一个文件,其中包含与此类似的格式的行...

/data/file.geojson?10,20,30,40
/data/file.geojson?bbox=-5.20751953125,49.05227025601607,3.0322265625,56.46249048388979
/data/file.geojson?bbox=-21.46728515625,45.99696161820381,19.2919921875,58.88194208135912
/data/file.geojson?bbox=-2.8482055664062496,54.38935426009769,-0.300750732421875,55.158473983815306
/data/file.geojson?bbox=-21.46728515625,45.99696161820381,19.2919921875,58.88194208135912
/data/file.geojson?bbox=-21.46728515625,45.99696161820381,19.2919921875,58.88194208135912

我尝试了grepsedgawk|(管道)的组合来尝试模式匹配,然后将格式更改为更多像这样...

[10,40],[30,40],[30,20][10,20],
[-5.20751953125,56.46249048388979],[3.0322265625,56.46249048388979].....

希望你能从第一行得到这个想法,所以我不必手动输入所有的例子!

我已经掌握了正则表达式,以配合坐标。实际上,输入文件是从apache访问日志中提取的结果。如果它们只是匹配正整数,则可能更容易阅读/理解答案,然后我将能够插入更多complicated pattern to match the right range

4 个答案:

答案 0 :(得分:2)

为了能够像你这样安排结果,能够访问最后一行的每行值。

如果您使用awk,则无需进行模式匹配。您可以通过一组分隔符拆分输入字符串,然后重新组合结果字段。 40可以$(NF)30访问$(NF-1),依此类推。

awk -F'[?,=]' '
    {printf "[%s,%s],[%s,%s],[%s,%s],[%s,%s]\n",
        $(NF-3),$(NF),$(NF-1),$(NF),
        $(NF-1),$(NF-2),$(NF-3),$(NF-2)
    }' file

我使用?,=作为字段分隔符。这样可以轻松访问感兴趣的列。

输出:

[10,40],[30,40],[30,20],[10,20]
[-5.20751953125,56.46249048388979],[3.0322265625,56.46249048388979],[3.0322265625,49.05227025601607],[-5.20751953125,49.05227025601607]
[-21.46728515625,58.88194208135912],[19.2919921875,58.88194208135912],[19.2919921875,45.99696161820381],[-21.46728515625,45.99696161820381]
[-2.8482055664062496,55.158473983815306],[-0.300750732421875,55.158473983815306],[-0.300750732421875,54.38935426009769],[-2.8482055664062496,54.38935426009769]
[-21.46728515625,58.88194208135912],[19.2919921875,58.88194208135912],[19.2919921875,45.99696161820381],[-21.46728515625,45.99696161820381]
[-21.46728515625,58.88194208135912],[19.2919921875,58.88194208135912],[19.2919921875,45.99696161820381],[-21.46728515625,45.99696161820381]

顺便说一下,sed也可以在这里使用:

sed -r 's/.*[?=]([^,]+),([^,]+),([^,]+),(.*)/[\1,\4],[\3,\4],[\3,\2],[\1,\2]/' file

该命令正在捕获每个单独捕获组中的数字,并在替换部分中重新组装它们。

并非sed的所有版本都支持+量词。最兼容的版本如下所示:)

sed 's/.*[?=]\([^,]\{1,\}\),\([^,]\{1,\}+\),\([^,]\{1,\}\),\(.*\)/[\1,\4],[\3,\4],[\3,\2],[\1,\2]/' file

答案 1 :(得分:1)

sed在数字之前剥离项目,然后awk以逗号分隔并以不同的顺序输出。假设数据位于名为" td.txt"

的文件中
sed 's/^[^0-9-]*//' td.txt|awk -F, '{print "["$1","$4"],["$3","$4"],["$3","$2"],["$1","$2"],"}'

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/^.*\?[^-0-9]*([^,]*),([^,]*),([^,]*),([^,]*)/[\1,\4],[\3,\4],[\3,\2],[\1,\2]/' file

或更多toothpicks

sed 's/^.*\?[^-0-9]*\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)/[\1,\4],[\3,\4],[\3,\2],[\1,\2]/' file

答案 3 :(得分:0)

您可以使用以下内容进行匹配:

(\/data\/file\.geojson\?(?:bbox=)?)([0-9.-]+),([0-9.-]+),([0-9.-]+),([0-9.-]+)

并替换为以下内容:

$1[$2,$3],[$4,$5]

请参阅DEMO