1

This question already has an answer here:

I am interested if there's a more elegant solution to the one posted below.

[]$ find ./abc -type f -exec sed -n 's/test/best/pg' {} + ; find ./abc -type f -exec sed -i 's/test/best/g' {} +

The first find sed command prints all found patterns to console. The second find sed command actually substitutes the patterns within file.

The problems I have encountered:

  1. sed -n -i (cannot have multiple command line modifier/arguments) -? someone confirm?

  2. sed does not have a native modifier to print results prior to substitution -? had trouble finding a solution, maybe it exists, and the command can be modified (i.e. below will output nothing, and substitute behind your back!).

    find ./abc -type f -exec sed -i 's/test/best/pg' {} +  
    

marked as duplicate by don_crissti, mikeserv, Scott, chaos, mdpc Dec 3 '15 at 0:29

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Maybe find [...] -exec grep test {}; sed -i 's/test/best/g' {} \;? – DopeGhoti Dec 2 '15 at 21:48
  • thanks @don_crissti I'm reading that article and haven't found a good solution I'm looking for. – MaestroCookies Dec 2 '15 at 21:51
  • @DopeGhoti, something more elegant, i.e. single command as opposed to using 2 commands. – MaestroCookies Dec 2 '15 at 21:53
  • That'll be tough, as by design sed modifies one stream of input and gives one stream of output; I don't think there's any way to have it take one input and give two outputs. – DopeGhoti Dec 2 '15 at 21:55
2

Well, you don't need to have two separate find commands:

find abc -type f -exec sed -n 's/test/best/pg' {} + -exec sed -i 's/test/best/g' {} +

... and you don't need the ./ in front of abc.

  • Because that doesn't work.  It's the worst of both worlds — it doesn't print anything, and it deletes all the lines in the file that don't match test. – G-Man Dec 2 '15 at 23:32
  • Oh, god. That's brainless enough I'm just going to delete it. Here: sed -ni '/test/w /dev/tty s//best/g; p' (w/ a newline after tty) – jthill Dec 2 '15 at 23:40
  • Note that jthill edited his/her comment since I posted my first response; the first version was sed -ni 's/test/best/pg' \{} +.  The revised version, sed -ni '/test/{p;s//best/g}' \{} +, is even worse: it still deletes all the lines in the file that don't match test, but it doesn't even do the requested substitution on the lines that do! – G-Man Dec 2 '15 at 23:41
  • sed -ni '/test/w /dev/tty s//best/g; p' doesn't work either.  If you think you have an answer, you should post an answer rather than critiquing a correct answer; comments are not good for multi-line text.  If you meant to have a newline rather than a space after /dev/tty, it still doesn't work (suggestion: try commands before you post them) but is coming close to answers that were posted to How to report “sed” in-place changes six months ago. – G-Man Dec 2 '15 at 23:50
  • You're right, of course. Started out brainless, continued that way. My apologies. – jthill Dec 2 '15 at 23:57
1

If you're on GNU/anything you can

find abc -type f -exec sed -i 's/test/best/gw /dev/fd/2' {} +

but in your text you mentioned wanting to print results prior to substitution, not sure what "results" means there but

find abc -type f -exec sed -i '/test/w /dev/fd/2
                               s//best/g' {} +

prints the lines that will change prior to substitution.

Not the answer you're looking for? Browse other questions tagged or ask your own question.