可以为模式grep文件,然后根据模式的部分对找到的行进行排序?

时间:2011-07-14 14:19:29

标签: regex grep

我将一些单独序列化的PHP数组存储到一个文件中。该文件的每一行包含一个序列化数组。例如:

a:2:{s:4:"name";s:8:"John Doe";s:3:"age";s:2:"20";}
a:2:{s:4:"name";s:8:"Jane Doe";s:3:"age";s:2:"15";}
a:2:{s:4:"name";s:12:"Steven Tyler";s:3:"age";s:2:"35";}
a:2:{s:4:"name";s:12:"Jim Morrison";s:3:"age";s:2:"25";}
a:2:{s:4:"name";s:13:"Apple Paltrow";s:3:"age";s:2:"75";}
a:2:{s:4:"name";s:12:"Drew Nickels";s:3:"age";s:2:"34";}
a:2:{s:4:"name";s:11:"Jason Proop";s:3:"age";s:2:"36";}

这是我的问题:

是否可以针对以下模式grep此文件:"name"*"*"

之后,我想根据第二个通配符的内容对找到的行进行排序。

2 个答案:

答案 0 :(得分:3)

以下是根据名称对行进行排序的方法。我已经分解了步骤,因此您可以看到中间输出。

> cat data.txt
a:2:{s:4:"name";s:8:"John Doe";s:3:"age";s:2:"20";}
a:2:{s:4:"name";s:8:"Jane Doe";s:3:"age";s:2:"15";}
a:2:{s:4:"name";s:12:"Steven Tyler";s:3:"age";s:2:"35";}
a:2:{s:4:"name";s:12:"Jim Morrison";s:3:"age";s:2:"25";}
a:2:{s:4:"name";s:13:"Apple Paltrow";s:3:"age";s:2:"75";}
a:2:{s:4:"name";s:12:"Drew Nickels";s:3:"age";s:2:"34";}
a:2:{s:4:"name";s:11:"Jason Proop";s:3:"age";s:2:"36";}

现在,我们将使用'sed'命令使用正则表达式提取名称。然后我们输出名称,选项卡,然后输出原始行,以便我们对其进行排序:

> cat data.txt | sed -rn 's/[^"]+"name";s:[0-9]+:"([^"]+)".*/\1\t\0/p'
John Doe        a:2:{s:4:"name";s:8:"John Doe";s:3:"age";s:2:"20";}
Jane Doe        a:2:{s:4:"name";s:8:"Jane Doe";s:3:"age";s:2:"15";}
Steven Tyler    a:2:{s:4:"name";s:12:"Steven Tyler";s:3:"age";s:2:"35";}
Jim Morrison    a:2:{s:4:"name";s:12:"Jim Morrison";s:3:"age";s:2:"25";}
Apple Paltrow   a:2:{s:4:"name";s:13:"Apple Paltrow";s:3:"age";s:2:"75";}
Drew Nickels    a:2:{s:4:"name";s:12:"Drew Nickels";s:3:"age";s:2:"34";}
Jason Proop     a:2:{s:4:"name";s:11:"Jason Proop";s:3:"age";s:2:"36";}

此sed命令要求'name'值为该行上的第一个引用字符串。如果您不能保证您应该使用php脚本实现此步骤并使用本机php函数反序列化数据。如果'name'不存在或者它不是该行中第一个引用的字符串,则将跳过该行。有关sed的更多信息,有许多在线资源。

现在名称首先在行上,我们可以使用普通的unix sort命令对它们进行排序:

> cat data.txt | sed -rn 's/[^"]+"name";s:[0-9]+:"([^"]+)".*/\1\t\0/p' | sort
Apple Paltrow   a:2:{s:4:"name";s:13:"Apple Paltrow";s:3:"age";s:2:"75";}
Drew Nickels    a:2:{s:4:"name";s:12:"Drew Nickels";s:3:"age";s:2:"34";}
Jane Doe        a:2:{s:4:"name";s:8:"Jane Doe";s:3:"age";s:2:"15";}
Jason Proop     a:2:{s:4:"name";s:11:"Jason Proop";s:3:"age";s:2:"36";}
Jim Morrison    a:2:{s:4:"name";s:12:"Jim Morrison";s:3:"age";s:2:"25";}
John Doe        a:2:{s:4:"name";s:8:"John Doe";s:3:"age";s:2:"20";}
Steven Tyler    a:2:{s:4:"name";s:12:"Steven Tyler";s:3:"age";s:2:"35";}

现在我们已经对线条进行了排序,我们只需要摆脱线条前面的简单名称:

> cat data.txt | sed -rn 's/[^"]+"name";s:[0-9]+:"([^"]+)".*/\1\t\0/p' | sort | cut -f2
a:2:{s:4:"name";s:13:"Apple Paltrow";s:3:"age";s:2:"75";}
a:2:{s:4:"name";s:12:"Drew Nickels";s:3:"age";s:2:"34";}
a:2:{s:4:"name";s:8:"Jane Doe";s:3:"age";s:2:"15";}
a:2:{s:4:"name";s:11:"Jason Proop";s:3:"age";s:2:"36";}
a:2:{s:4:"name";s:12:"Jim Morrison";s:3:"age";s:2:"25";}
a:2:{s:4:"name";s:8:"John Doe";s:3:"age";s:2:"20";}
a:2:{s:4:"name";s:12:"Steven Tyler";s:3:"age";s:2:"35";}

享受!

答案 1 :(得分:3)

我不确定grepping在哪里,因为你的所有线条都与模式相匹配。但无论如何,您可以单独使用sort来对样本输入进行排序:

sort -t\" -k4 data.txt

它忽略了文本的“真实”结构,它只是将"视为分隔符,所以它快速而又脏,但它可以按你想要的方式排序。这是在行动:

http://ideone.com/ZugIX

如果你确实需要为"name".*".*" grep,你可以先执行此操作并将输出通过管道输出到sort