单线应该:
解决现实世界的问题
不是非常神秘(应该易于理解和重现)
值得花时间写它(不应该太聪明)
我正在寻找实用的技巧和窍门(补充例子perldoc perlrun
).
请参阅我的幻灯片"Perl命令行选项的字段指南".
问题:由于媒体播放器的名称与相应的视频文件不同,因此媒体播放器不会自动加载字幕.
解决方案:重命名所有*.srt(带字幕的文件)以匹配*.avi(带视频的文件).
perl -e'while(<*.avi>) { s/avi$/srt/; rename <*.srt>, $_ }'
CAVEAT:原始视频和字幕文件名的排序顺序应该相同.
这里是上述单行的更详细版本:
my @avi = glob('*.avi'); my @srt = glob('*.srt'); for my $i (0..$#avi) { my $video_filename = $avi[$i]; $video_filename =~ s/avi$/srt/; # 'movie1.avi' -> 'movie1.srt' my $subtitle_filename = $srt[$i]; # 'film1.srt' rename($subtitle_filename, $video_filename); # 'film1.srt' -> 'movie1.srt' }
Squid日志文件.他们很棒,不是吗?除了默认情况下,它们具有从时间开始的秒数作为时间字段.这是一个单行程序,它从squid日志文件中读取并将时间转换为人类可读日期:
perl -pe's/([\d.]+)/localtime $1/e;' access.log
通过小调整,您可以只使用您感兴趣的关键字显示行.以下为stackoverflow.com的监视访问并打印那些具有人类可读日期的行.为了使它更有用,我给它输出tail -f
,所以我可以实时看到访问:
tail -f access.log | perl -ne's/([\d.]+)/localtime $1/e,print if /stackoverflow\.com/'
您可能不会将其视为Perl,但我虔诚地使用ack(它是用Perl编写的智能grep替换)并且允许我编辑,例如,我访问API的特定部分的所有Perl测试:
vim $(ack --perl -l 'api/v1/episode' t)
作为旁注,如果使用vim,则可以在编辑器的缓冲区中运行所有测试.
对于更明显(如果简单)Perl的东西,我需要知道在t/lib/TestPM目录中有多少测试程序使用了测试装置(为了清楚起见,我已经减少了命令).
ack $(ls t/lib/TestPM/|awk -F'.' '{print $1}'|xargs perl -e 'print join "|" => @ARGV') aggtests/ t -l
注意"join"如何将结果转换为正则表达式以提供给ack.
find ... -exec rm {} \;
用于删除目录树中某处文件集的常用习惯用法不是特别有效,因为它对rm
找到的每个文件执行一次命令.我的一个习惯是从计算机不太快(dagnabbit!)的那些日子开始,rm
用一次调用perl 来代替许多调用:
find . -name '*.whatever' | perl -lne unlink
perl
命令行的一部分读取*by发出的文件列表find
,每行一个,修剪新行,并使用perl的内置unlink()
函数删除文件,$_
如果没有提供显式参数,则将其作为参数.($_
由于-n
标志,设置为每行输入.)(*这些天,大多数find
命令-print
默认都这样做,所以我可以把那部分放掉.)
我喜欢这个成语不仅因为效率(这些日子可能不那么重要),而且因为它比键入传统的-exec rm {} \;
序列有更少的chorded/awkward键.它还避免引用由空格,引号等文件名引起的问题,我有很多.(更强大的版本可能会使用find
's -print0
选项然后要求perl
读取空分隔的记录而不是行,但我通常非常确信我的文件名不包含嵌入的换行符.)
在一个地方收集答案的所有单行:
perl -pe's/([\d.]+)/localtime $1/e;' access.log
ack $(ls t/lib/TestPM/|awk -F'.' '{print $1}'|xargs perl -e 'print join "|" => @ARGV')
aggtests/ t -l
perl -e'while(<*.avi>) { s/avi$/srt/; rename <*.srt>, $_ }'
find . -name '*.whatever' | perl -lne unlink
tail -F /var/log/squid/access.log | perl -ane 'BEGIN{$|++} $F[6] =~ m{\Qrad.live.com/ADSAdClient31.dll}
&& printf "%02d:%02d:%02d %15s %9d\n", sub{reverse @_[0..2]}->(localtime $F[0]), @F[2,4]'
export PATH=$(perl -F: -ane'print join q/:/, grep { !$c{$_}++ } @F'<<<$PATH)
alias e2d="perl -le \"print scalar(localtime($ARGV[0]));\""
perl -ple '$_=eval'
perl -00 -ne 'print sort split /^/'
perl -pe'1while+s/\t/" "x(8-pos()%8)/e'
tail -f log | perl -ne '$s=time() unless $s; $n=time(); $d=$n-$s; if ($d>=2) { print qq
($. lines in last $d secs, rate ),$./$d,qq(\n); $. =0; $s=$n; }'
perl -MFile::Spec -e 'print join(qq(\n),File::Spec->path).qq(\n)'
请参阅相应的答案以获取其说明
我使用的Perl单线程是Perl计算器
perl -ple '$_=eval'