我一直试图做一些perl正则表达式并且已经碰壁了。 我正在尝试对日志文件进行一些数据分析,我遇到了以下问题:
我有一个文件test.csv,它由来自另一个程序的多个单行条目组成,它产生以下布局格式:
我想要做的是从路径列表中删除文件名,因此生成的文件将包含:
我已经把头撞在墙上了,试过各种perl正则表达式试图在没有太多运气的情况下删除文件名。由于目录的路径长度各不相同,我正在撞墙,我不确定这是否可以在perl或python中完成。
答案 0 :(得分:4)
你可以用Perl中的一行来完成这个:
perl -pe 's/[^\\]+$/\n/' <infile.txt >outfile.txt
把它分成几部分:
-p
导致Perl在-e
循环中包装语句(随while
提供),将语句应用于输入文件的每一行,并打印结果。
-e
为Perl提供了一条针对每一行的语句。
s/[^\\]+$/\n/
是一个替换语句,它使用正则表达式将不包括行尾的反斜杠的任何字符序列更改为换行符\n
。
[^\\]
是一个正则表达式,匹配任何不是反斜杠的单个字符
[^\\]+
是一个正则表达式,匹配一个或多个不是反斜杠的字符
[^\\]+$
是一个正则表达式,匹配一个或多个字符,这些字符不是反斜杠后跟行尾
答案 1 :(得分:3)
使用正则表达式可能会有效,但使用专为此目的设计的模块通常更好。 File::Basename
或File::Spec
是用于此目的的合适核心模块:
<强>代码:强>
use strict;
use warnings;
use v5.10;
use File::Basename;
say dirname($_) for <DATA>;
__DATA__
d:\snow\dir.txt
d:\snow\history\dir.tff
d:\snow\history\help.jar
d:\winter\show\help.txt
d:\summer\beach\ocean\swimming.txt
<强>输出:强>
d:\snow
d:\snow\history
d:\snow\history
d:\winter\show
d:\summer\beach\ocean
当然,如果你想要结束反斜杠,你必须添加它们。
对于File::Spec
:
my ($volume, $dir, $file) = File::Spec->splitpath($path);
my $wanted_path = $volume . $dir; # what you want
这两个模块长期以来一直是核心发行版的一部分,这是一个很好的好处。
答案 2 :(得分:0)
你也可以使用这个衬垫
perl -pe s /\\\\\w+\.\w+$// test.csv > Output.txt
\w+\.\w+$
匹配文件名,扩展名位于路径末尾
答案 3 :(得分:0)
这是在Python中实现它的一种方法:
python -c 'import sys,re;[sys.stdout.write(re.sub("[^\\\]+$","\n",l))for l in sys.stdin]' < in.txt > out.txt
我承认它比Perl解决方案更冗长。