0

How can I run a replacement in sed only when part of a line I don't want to replace includes one of a list of substrings?

For example, say, the substrings used to mark lines I want to replace are 123, 456 and abc in the following sample input:

# jdggsdihdf, 123
# ljhkhkjh, 789
# fagdfhgghjasfa, 456
# jsajspjsdighishxc, abc
# jgasdjGA, def

Thus, only those lines should be modified, and the lines with 789 or def should be left alone:

Replaced text, 123
# ljhkhkjh, 789
Replaced text, 456
Replaced text, abc
# jgasdjGA, def

I know how to do simple s/foo/bar/ replacements, so I could do s/^# .*,/Replaced text,/, but I don't know how to do that only when the line also matches a string in one of the fields I don't want to change with the replacement.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Chris
  • 985
  • 2
  • 7
  • 17
  • 2
    One question per question, please. – Kenster May 12 '18 at 18:47
  • ...with a title specific to that individual question. Our goal is to build a knowledgebase with every question one might separately have individually asked; when you combine multiple questions to a post, we then lose the ability to select the best, most canonical instance of each individual question and build a single answer to it (vs having a potentially-conflicting answer on each instance). Moreover, a generic title means others with the same problem *can't find your question*, making it less useful to others. – Charles Duffy May 12 '18 at 18:49
  • Should I remkae this? – Chris May 12 '18 at 18:57
  • I edited it. Hope thats better? – Chris May 12 '18 at 19:34
  • can you clean it up? – Chris May 12 '18 at 19:34
  • Much better, yes. (Ideally, you'd also show what you tried and how it failed, or explain what part of the problem was messing you up -- for instance, "I know how to do a string replacement, but not how to do that only on lines that also match a specific regex"). – Charles Duffy May 12 '18 at 20:04
  • I believe what you want is `sed -re '/123\|456\|abc/{ s/^# .*,/Replaced text,/ }'`; I'll add that as an answer if we have a successful reopen vote. – Charles Duffy May 12 '18 at 20:15
  • You worded it much nice. Thanks. Sorry for bad english. It still says it is on hold. Is this bad? – Chris May 12 '18 at 20:16
  • So, it takes 5 people to vote to close a question (usually, there are some exceptions -- elected moderators can operate on their own, and certain kinds of close votes can be done by people with lots of reputation in a tag), so it takes 5 people to vote to re-open it again after it's been improved. I already voted to re-open it; perhaps others will as well. – Charles Duffy May 12 '18 at 20:16
  • OTOH, a reopen vote might not be needed here, since we already do have a question at https://stackoverflow.com/questions/6684857/how-to-skip-lines-matching-a-string that covers the topic. (The question isn't clear there if they want to delete or ignore non-matching lines, so the answer covers both). – Charles Duffy May 12 '18 at 20:20
  • (oops, I should have had *either* the `-r` flag *or* the backslashes before the `|`s in the approach suggested in my comment above, but not both -- sorry about that!) – Charles Duffy May 12 '18 at 20:23

1 Answers1

1

For 1st question:

sed 's/^#.*,/replaced_text/'  Input_file

For 2nd question:

sed 's/\, [^ ]*/,/' Input_file

To modify the Input_file itself use sed -i option, to take backup of Input_file use sed -i.bak option too.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93