Reputation: 929
Problem:
Many files name.CFG with some bad lines in them (roughly 2700 files). I need to remove the bad lines if they exist.
The bad lines contain the name of the file minus the .CFG
The Bad Lines:
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
is the name of the file minus the .CFG
I was looking for a linux way to do this, but it seems as though Perl would be more flexible. My real issue is matching the text exactly. I guess having the multiple lines and variable are what is perplexing to me, but a small string you could do a find and replace kind of thing. Or use SED
.
I need to remove the bad lines from all of the files.
Upvotes: 2
Views: 97
Reputation: 5347
perl -i.bak -ne '$n=$ARGV=~s/\.cfg$//r; print unless /\b$n\b/' *.cfg
or even
... print unless /\b\Q$n\E\b/
It will create a backup (file.cfg.bak)
Upvotes: 1
Reputation: 51330
This will do the trick (although I believe there's a more efficient way to do this):
find -iname '*.cfg' -execdir perl -i -ne '$f = $ARGV =~ s#\./|\.cfg##gr; print if !m/\b\Q$f\E\b/;' {} \+
If you're on windows, you need to provide a backup file name for the inplace (-i
) feature:
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'
finds every .cfg
file in the current directory and all subdirectories.
The Perl script is:
# 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/;
Upvotes: 2
Reputation: 784958
Using grep -P
(PCRE):
grep -P 'nameofdevice(?!\.CFG)' file
To skip these lines:
grep -v -P 'nameofdevice(?!\.CFG)' file > tmpFile
mv tmpFIle file
Upvotes: 1