122

I am trying

grep searchterm myfile.csv | sed 's/replaceme/withthis/g'

and getting

unknown option to `s'

What am I doing wrong?

Edit:

As per the comments the code is actually correct. My full code resembled something like the following

grep searchterm myfile.csv | sed 's/replaceme/withthis/g'
# my comment

And it appears that for some reason my comment was being fed as input into sed. Very strange.

deltanovember
  • 42,611
  • 64
  • 162
  • 244
  • Do you want to replace your file with 'withthis' in the place of replacename? – Teja Apr 02 '12 at 22:33
  • 2
    No, that's not what you're trying. There's something else missing. – Ignacio Vazquez-Abrams Apr 02 '12 at 22:33
  • 7
    My best guess is that in your real case you have a `/` in `replaceme` or `withthis`. Try: `'s#replaceme#withthis#g'`. – cababunga Apr 02 '12 at 22:38
  • 4
    One thing that you're doing wrong is not showing us exactly what you are executing. The code you show is fine; you've got a problem with what you're executing; ergo, you are not showing us what you're executing. We can't debug what we can't see, most of the time. Sometimes, we'll get lucky and guess right, but we shouldn't be having to guess or be lucky. – Jonathan Leffler Apr 02 '12 at 22:38
  • 1
    Useless use of grep. With sed, you can do: sed '/searchterm/s/pattern/replacement/g' myfile.csv – William Pursell Apr 03 '12 at 06:07

5 Answers5

161

use the --expression option

grep searchterm myfile.csv | sed --expression='s/replaceme/withthis/g'
Elijah Lynn
  • 12,272
  • 10
  • 61
  • 91
Ben Davis
  • 13,112
  • 10
  • 50
  • 65
  • +SOaddict, This is just outputting to stdout, it isn't changing the myfile.csv. – Josiah Apr 29 '16 at 20:12
  • 1
    If you are wanting to do an in-place update of the file, I think my answer adequately solves that issue. – Wes May 10 '19 at 15:50
  • 2
    Anything which looks like `grep 'x' y | sed 'z'` can be refactored to `sed '/x/z' y`. See also [useless use of `grep`.](http://www.iki.fi/era/unix/award.html#grep) – tripleee Sep 25 '20 at 09:12
  • Most devs aren't going to know the shorthand way to do something within a language they likely don't also know how to do the long way – Wes Apr 05 '22 at 04:07
62

use "-e" to specify the sed-expression

cat input.txt | sed -e 's/foo/bar/g'
umläute
  • 28,885
  • 9
  • 68
  • 122
  • 1
    I was wondering how using "-e" to specify the sed-expression can get sed to read from stdin? Does sed by default read from stdin? – Tim Aug 20 '17 at 05:53
  • 1
    yes. like most un*x tools, `sed` reads from stdin if no input file is present. – umläute Aug 21 '17 at 07:32
  • Thanks. is `-e` necessary? It works without `-e`. I wonder what's the purpose of using `-e`? Thanks. – Tim Aug 21 '17 at 09:41
  • 2
    I am not sure I understand the question of OP. `echo foo | sed 's/foo/bar/g'` works without `-e`, by outputing `bar`. So I must have missed his question. – Tim Aug 21 '17 at 10:30
  • 1
    There is no need to specify `-e` if you only have a single script statement. If you have two, you can say `sed -e '/foo/!d' -e 's//bar/g'` or `sed 's/foo!d;s//bar/g'` (or equivalently, with a newline instead of a semicolon). – tripleee Sep 25 '20 at 09:11
  • The [`cat` is useless.](/questions/11710552/useless-use-of-cat) – tripleee Sep 25 '20 at 09:11
  • @tripleee the question specifically asks about how to use `stdin`; the `cat` is there as a placeholder to generate a stdin, not to demonstrate how to get the input of a file into `sed`. also, thanks for commenting on an 8 year old answer ;-) – umläute Sep 26 '20 at 21:44
7

To make sed catch from stdin , instead of from a file, you should use -e.

Like this:

curl -k -u admin:admin https://$HOSTNAME:9070/api/tm/3.8/status/$HOSTNAME/statistics/traffic_ips/trafc_ip/ | sed -e 's/["{}]//g' |sed -e 's/[]]//g' |sed -e 's/[\[]//g' |awk  'BEGIN{FS=":"} {print $4}'
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
LeoChu
  • 726
  • 6
  • 6
  • -e has nothing to to with input redirection from what I've seen. Instead, your use of -e would eliminate calling sed multiple times. You can pipe the output independent of -e – Brian Jan 08 '23 at 00:55
3

If you are trying to do an in-place update of text within a file, this is much easier to reason about in my mind.

grep -Rl text_to_find directory_to_search 2>/dev/null | while read line; do  sed -i 's/text_to_find/replacement_text/g' $line; done

Wes
  • 467
  • 3
  • 11
-21
  1. Open the file using vi myfile.csv
  2. Press Escape
  3. Type :%s/replaceme/withthis/
  4. Type :wq and press Enter

Now you will have the new pattern in your file.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Teja
  • 13,214
  • 36
  • 93
  • 155