匹配一些行并用Perl删除它们

时间:2015-02-23 08:07:13

标签: regex perl

问题

许多文件名称.CFG中包含一些坏行(大约2700个文件)。如果它们存在,我需要删除坏线。

坏行包含文件名减去.CFG

错误行

Title[nameofdevice:cpu]: nameofdevice CPU Usage Mhz
Target[nameofdevice:cpu]:
MaxBytes[nameofdevice:cpu]: 100
Options[nameofdevice:cpu]: gauge
WithPeak[nameofdevice:cpu]: wmy
YLegend[nameofdevice:cpu]: Percent
ShortLegend[nameofdevice:cpu]: %
Legend1[nameofdevice:cpu]: CPU % for 1
Legend2[nameofdevice:cpu]: CPU Max for 2
Legend3[nameofdevice:cpu]: Max CPU Mhz for 1
Legend4[nameofdevice:cpu]: Max CPU Mhz for 2

Title[nameofdevice:mem]: nameofdevice mem
Target[nameofdevice:mem]:
MaxBytes[nameofdevice:mem]: 100
Options[nameofdevice:mem]: gauge
WithPeak[nameofdevice:mem]: wmy
YLegend[nameofdevice:mem]: Percent
ShortLegend[nameofdevice:mem]: %
Legend1[nameofdevice:mem]: % Used
Legend2[nameofdevice:mem]: Max Used
Legend3[nameofdevice:mem]: Max

nameofdevice是文件名减去.CFG

我一直在寻找一种方法来实现这一点,但似乎Perl会更灵活。我真正的问题是完全匹配文本。我想拥有多行和变量是令我困惑的东西,但是一个小字符串你可以做一个查找和替换的东西。或者使用SED

我需要删除所有文件中的坏行。

3 个答案:

答案 0 :(得分:2)

这可以解决问题(虽然我相信这是一种更有效的方法):

find -iname '*.cfg' -execdir perl -i -ne '$f = $ARGV =~ s#\./|\.cfg##gr; print if !m/\b\Q$f\E\b/;' {} \+

如果您使用的是Windows,则需要为 inplace -i)功能提供备份文件名:

find -iname '*.cfg' -execdir perl -ibak -ne '$f = $ARGV =~ s#\./|\.cfg##gr; print if !m/\b\Q$f\E\b/;' {} \+ && find -iname '*.cfgbak' -delete

find -iname '*.cfg'查找当前目录和所有子目录中的每个.cfg文件。

Perl脚本是:

# there's an implied while(<>) because of the -n option
# which executes this script for each line

# $ARGV is the current file path, strip ./ and .cfg
$f = $ARGV =~ s#\./|\.cfg##gr;

# print the current line if it doesn't contain the current file name
# as a whole word
print if !m/\b\Q$f\E\b/;

答案 1 :(得分:1)

使用grep -P(PCRE):

grep -P 'nameofdevice(?!\.CFG)' file

要跳过这些内容:

grep -v -P 'nameofdevice(?!\.CFG)' file > tmpFile
mv tmpFIle file

答案 2 :(得分:1)

perl -i.bak -ne '$n=$ARGV=~s/\.cfg$//r; print unless /\b$n\b/' *.cfg

甚至

... print unless /\b\Q$n\E\b/

它将创建一个备份(file.cfg.bak)