Trying to avoid a perl script which wouldn't be hard, but I am looking for an awk one liner that does a replacement, but only after it sees a key word on some line.
Anyone know of that's easy to do?
Thanks! jlc
On Fri, 2010-03-26 at 00:36 +0000, Joseph L. Casale wrote:
Trying to avoid a perl script which wouldn't be hard, but I am looking for an awk one liner that does a replacement, but only after it sees a key word on some line.
Anyone know of that's easy to do?
Thanks!
---- sounds more like a reason to use sed
man sed or tell us exactly what you are trying to do
Craig
sounds more like a reason to use sed
man sed or tell us exactly what you are trying to do
Tell you the truth, I would much rather use sed, but I didn't think that was doable with it.
I have a slew of txt files that contain a keyword like "service-one" on many lines. I need to change those, but only the ones that appear _after_ a known comment.
Thanks! jlc
Joseph L. Casale wrote:
sounds more like a reason to use sed
man sed or tell us exactly what you are trying to do
Tell you the truth, I would much rather use sed, but I didn't think that was doable with it.
I have a slew of txt files that contain a keyword like "service-one" on many lines. I need to change those, but only the ones that appear _after_ a known comment.
Can you use a regexp like: s/(known_part)(.*)(change_part)/\1\2replace_part/
Can you use a regexp like: s/(known_part)(.*)(change_part)/\1\2replace_part/
Unless I misunderstand that, I'd say no.
The actual file might look this:
/begin file
foo bar{ biz service-one baz service-two }
--many more of that--
# comment
fiz bir{ aaa service-one bbb service-two }
/end file
So only after the "# comment", I want to then start replacing. I am just trying to replace a very ugly long set of commands piped into each other that I am using now.
Thanks! jlc
Joseph L. Casale wrote:
Can you use a regexp like: s/(known_part)(.*)(change_part)/\1\2replace_part/
Unless I misunderstand that, I'd say no.
The actual file might look this:
/begin file
foo bar{ biz service-one baz service-two }
--many more of that--
# comment
fiz bir{ aaa service-one bbb service-two }
/end file
So only after the "# comment", I want to then start replacing. I am just trying to replace a very ugly long set of commands piped into each other that I am using now.
I think there is a way to do it in sed using the holding space, but it's so much easier in perl that I never bothered to learn the hard parts. What's the problem with using perl anyway?
I think there is a way to do it in sed using the holding space, but it's so much easier in perl that I never bothered to learn the hard parts. What's the problem with using perl anyway?
No problem, just thought there was a sexier way to do it then my ugly way. The Perl solution would be just as long if it were a one liner, so I'll just shove it into a shell script I guess.
Thanks! jlc
On 03/26/2010 02:02 PM, Joseph L. Casale wrote:
I think there is a way to do it in sed using the holding space, but it's so much easier in perl that I never bothered to learn the hard parts. What's the problem with using perl anyway?
No problem, just thought there was a sexier way to do it then my ugly way. The Perl solution would be just as long if it were a one liner, so I'll just shove it into a shell script I guess.
i you're worried about slurping the whole file
perl -pe '/# comment/ and $c=1; $c and s/service-one/foo-bar/g' \ test_file.txt
works for me
slurping the whole files and replacing inline (with backups) you could do
perl -i.save -0777 -pe \ 's/(# comment)(.*)(service-one)/$1$2 foobar/msg' file1 file2 ...
K
On Thu, Mar 25, 2010 at 5:36 PM, Joseph L. Casale jcasale@activenetwerx.com wrote:
Trying to avoid a perl script which wouldn't be hard, but I am looking for an awk one liner that does a replacement, but only after it sees a key word on some line.
Anyone know of that's easy to do?
Depends on how you define "one-liner." Something like this might work:
{ if index($0, PATTERN) != 0 {FOUND = 1;}; if (FOUND != 0) {subst(REPLACE_THIS, WITH_THIS, $0); }
You'd want to reverse the order of the two statements if the replacement is only to occur after the pattern is found.
Now, if you want to process multiple files, you'd have to reset the found flag when the filename changes, and that's another if-else clause, which gets kind of long for a "one liner."
It's ugly, but it's awk....
mhr
Depends on how you define "one-liner." Something like this might work:
{ if index($0, PATTERN) != 0 {FOUND = 1;}; if (FOUND != 0) {subst(REPLACE_THIS, WITH_THIS, $0); }
You'd want to reverse the order of the two statements if the replacement is only to occur after the pattern is found.
Cool, I'll give it a whirl tomorrow! I do want to replace all occurrences only after the keyword Thanks, jlc
Depends on how you define "one-liner." Something like this might work:
{ if index($0, PATTERN) != 0 {FOUND = 1;}; if (FOUND != 0) {subst(REPLACE_THIS, WITH_THIS, $0); }
You'd want to reverse the order of the two statements if the replacement is only to occur after the pattern is found.
Cool, I'll give it a whirl tomorrow! I do want to replace all occurrences only after the keyword
When you say "after", do you mean blah, blah blah, blah yadda, yadda, keyword, to-be-replaced
or do you mean blah, blah blah, blah yadda, yadda, keyword, to-be-replaced also-to-be-replaced?
mark "awk 'r' us"
or do you mean blah, blah blah, blah yadda, yadda, keyword, to-be-replaced also-to-be-replaced?
Yup, the keyword marks the position where I then start looking for matches. Once I get to work, I will give these a try.
Thanks guys!
Sure. And what you want is just { if ($0 ~ /keyword/ ) { start = 1; } if ( start == 1 ) { sub( str, repl ); print $0; } }
mark
On Fri, Mar 26, 2010 at 7:28 AM, m.roth@5-cent.us wrote:
or do you mean blah, blah blah, blah yadda, yadda, keyword, to-be-replaced also-to-be-replaced?
Yup, the keyword marks the position where I then start looking for matches. Once I get to work, I will give these a try.
Thanks guys!
Sure. And what you want is just { if ($0 ~ /keyword/ ) { start = 1; } if ( start == 1 ) { sub( str, repl ); print $0; } }
That will start the replacements on the same line that the keyword is found.
mhr
or do you mean
blah, blah blah,
blah
yadda, yadda,
keyword,
to-be-replaced also-to-be-replaced?
Yup, the keyword marks the position where I then start looking for matches. Once I get to work, I will give these a try.
Thanks guys!
Sure. And what you want is just { if ($0 ~ /keyword/ ) { start = 1; } if ( start == 1 ) { sub( str, repl ); print $0;
} }
If you make this a little more awky then you get the one liner:-
awk '(start==1){gsub(/str/,"repl")}/keyword/{start=1}{print $0}' input_file.txt
where keyword is the trigger phrase, str is a regexp to find, repl is the string to replace the regexp with, and input_file.txt is obviously your data file (I'm assuming you want to print all the lines not just the replaced ones)
If you only want to replace matches on lines after the one with keyword then refining it slightly to:
awk '(start==1){gsub(/str/,"repl");continue}/keyword/{start=1}{print $0}' input_file.txt
should work.
chris