1

I am looking to creating a .sh file where it would read a file specified, look for a specific text and replace the section with some other text.

Suppose we have somefile.js.

Can a shell script look for this:

"scripts": [
  "../node_modules/something.js"
],

and replace it with

"scripts": [
  "../node_modules/something1.js",
  "../node_modules/something2.js"
],

Can this be done at all? If so how?

Markus
  • 2,071
  • 4
  • 22
  • 44
  • What have you tried? I guess youre not expecting us to write the whole script for you. ;) – Markus Jun 22 '17 at 09:04
  • I just need to know if this can be done. I'm not asking for a scipt just the way to replace specified text from a file (If it can be done) –  Jun 22 '17 at 09:22

2 Answers2

0

Yes, you can use sed to replace texts in files.

sed '/s/one/two/' < old.txt > new.txt

This small example replaces all one with two in old.txt and outputs the result in new.txt.

Markus
  • 2,071
  • 4
  • 22
  • 44
  • That's definitely NOT how to do what the OP is trying to do and in fact it's not even valid sed syntax. And yet it's the accepted answer - makes you wonder.... – Ed Morton Jun 25 '17 at 13:19
  • Thanks for pointing out the syntax error. For this specific case the use of sed should be more than sufficient. There might be corner cases. But from my point of view the used example suggests that the OP wants to manage sth like package.json-files which are usually created by npm automatically and therefore cover not to many variations. – Markus Jun 25 '17 at 17:06
  • The OP is trying to replace an arbitrary multi-line block with another arbitrary multi-line block - s/old/new will clearly not do that (you'd need to figure out how to read in multiple lines at a time then handle the `/`s and any regexp metachars in the `old` text and any backreferences in the `new` text`) and is the wrong starting point for even attempting to do that. – Ed Morton Jun 25 '17 at 17:12
0

sed is for simple substitutions on individual lines, that is all. For anything else you should use awk for clarity, robustness, efficiency, etc. etc. See Is it possible to escape regex metacharacters reliably with sed for some of the hoops you'd have to jump through to even BEGIN thinking about coming up with a robust sed script to do this job.

The simple, robust way to do what you want (in this case using GNU awk for multi-char RS):

$ cat tst.awk
BEGIN { RS="^$"; ORS="" }
ARGIND==1 { old=$0; next }
ARGIND==2 { new=$0; next }
s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+length(old)) }
{ print }

$ cat old
"scripts": [
  "../node_modules/something.js"
],

$ cat new
"scripts": [
  "../node_modules/something1.js",
  "../node_modules/something2.js"
],

$ cat file
foo
"scripts": [
  "../node_modules/something.js"
],
bar

$ awk -f tst.awk old new file
foo
"scripts": [
  "../node_modules/something1.js",
  "../node_modules/something2.js"
],
bar
Ed Morton
  • 188,023
  • 17
  • 78
  • 185