2

I have a test file having around 20K lines in that file I want to change some specific string in specific lines I am getting the line number and strings to change.here I have a scenario where I want to change the one string to another in multiple lines. I used earlier like

sed -i '12s/stringone/stringtwo/g'   filename

but in this case I have to run the multiple commands for same test like

sed -i '15s/stringone/stringtwo/g'   filename
sed -i '102s/stringone/stringtwo/g'   filename
sed -i '11232s/stringone/stringtwo/g'   filename

Than I tried below

sed -i '12,15,102,11232/stringone/stringtwo/g' filename

but I am getting the error

sed: -e expression #1, char 5: unknown command: `,'

Please some one help me to achieve this.

oliv
  • 12,690
  • 25
  • 45
ram
  • 323
  • 4
  • 12
  • sed cannot operate with literal strings (see https://stackoverflow.com/q/29613304/1745001) so if you truly want to do that then you'e using the wrong tool. [edit] your question to include concise, testable sample input and expected output and make sure to include regexp and backreference metachars if they can occur. – Ed Morton Jul 09 '18 at 13:36

3 Answers3

1

To get the functionality you're trying to get with GNU sed would be this in GNU awk:

awk -i inplace '
BEGIN {
    split("12 15 102 11232",tmp)
    for (i in tmp) lines[tmp[i]]
}
NR in lines { gsub(/stringone/,"stringtwo") }
' filename

Just like with a sed script, the above will fail when the strings contain regexp or backreference metacharacters. If that's an issue then with awk you can replace gsub() with index() and substr() for string literal operations (which are not supported by sed).

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

You get the error because the N,M in sed is a range (from N to M) and doesn't apply to a list of single line number.

An alternative is to use printf and sed:

sed -i "$(printf '%ds/stringone/stringtwo/g;' 12 15 102 11232)" filename

The printf statement is repeating the pattern Ns/stringone/stringtwo/g; for all numbers N in argument.

oliv
  • 12,690
  • 25
  • 45
1

This might work for you (GNU sed):

sed '12ba;15ba;102ba;11232ba;b;:a;s/pattern/replacement/' file

For each address, branch to a common place holder (in this case :a) and do a substitution, otherwise break out of the sed cycle.

If the addresses were in a file:

sed 's/.*/&ba/' fileOfAddresses | sed -f - -e 'b;:a;s/pattern/replacement/' file 
potong
  • 55,640
  • 6
  • 51
  • 83