【发布时间】:2018-09-15 17:47:09
【问题描述】:
我正在尝试使用 Perl 重新排序 md5 文件的内容。对于每一行,我想要没有路径的文件名,然后是哈希。我想出的最好的命令是:
$ perl -pe 's|^([[:alnum:]]+).*?([^/]+)$|$2 $1|' DCIM.md5
输入文件 (DCIM.md5) 在 Linux 上由md5sum 生成。它看起来像这样:
e26ff03dc1bac80226e200c0c63d17a2 ./Path1/IMG_20150201_160548.jpg
01f92572e4c6f2ea42bd904497e4f939 ./Path 2/IMG_20150204_190528.jpg
afce027c977944188b4f97c5dd1bd101 ./Path3/Path 4/IMG_20151011_193008.jpg
- 哈希与
中的第一组([[:alnum:]]+)匹配 正则表达式。 - 那么空格和文件路径是
由.*?匹配。 - 然后文件名匹配
([^/]+)。 - 表达式用
^括起来(这里显然没有必要) 和$。没有$,表达式不会输出我所期望的。 - 我使用
|而不是/作为分隔符以避免在文件路径中转义。
该命令返回:
IMG_20150201_160548.jpg
e26ff03dc1bac80226e200c0c63d17a2IMG_20150204_190528.jpg
01f92572e4c6f2ea42bd904497e4f939IMG_20151011_193008.jpg
afce027c977944188b4f97c5dd1bd101IMG_20151011_195133.jpg
匹配正确,输出序列正确(文件名没有路径,然后是哈希)但间距不正确:文件名后面有一个换行符。我希望它在哈希之后,像这样:
IMG_20150201_160548.jpg e26ff03dc1bac80226e200c0c63d17a2
IMG_20150204_190528.jpg 01f92572e4c6f2ea42bd904497e4f939
IMG_20151011_193008.jpg afce027c977944188b4f97c5dd1bd101
在我看来,我的命令输出了换行符,但我不知道如何改变这种行为。 或者问题可能来自 shell,而不是命令?
最后,一些版本信息:
$ perl -version
This is perl 5, version 22, subversion 1 (v5.22.1) built for i686-linux-gnu-thread-multi-64int
(with 69 registered patches, see perl -V for more detail)
【问题讨论】:
-
[^/]将匹配非斜杠(包括换行符)。也许试试[^\n/] -
如果你匹配一个十六进制字符串,那么最好使用
[[:xdigit:]]而不是[[:alnum:]]。或者,Unicode 属性\p{Hex}更简洁、更现代。 -
我认为您在解决此问题方面的工作(“您的”指的是 OP),尤其是您获取文件名的策略,非常巧妙!我会将它与给出的答案结合起来。它会比我平时的更好:
s|^.*/(.*)$|$1|方法(必须与@Shawn 讨论的-l开关以及您使用的-p开关一起使用)。我会找到perl -lpe 's|([^/])$|$1|来查找文件名是一行中的最后一个条目。我喜欢它! -
另外一个建议:使用
[:xdigit:]而不是[:alnum:],以帮助解决(当然不太可能)得到一行不是以有效哈希开头的情况。 -
@ChrisCharley,
[^/]将匹配换行符是非常正确的。我是否正确地推测它实际上是后面的加号,即<code>[^/] +</code>,导致这种行为成为问题?