0

I want to find a string in a file and replace with with something, but the following command doesn't work.

$ grep "CUDA_ARCH" lib/gpu/Makefile.linux | grep -v "#CUDA_ARCH" | grep -v " CUDA_ARCH " | xargs sed -i 's/sm_.*/sm_86/g'
sed: invalid option -- 'a'
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

The following commands are correct

$ grep "CUDA_ARCH" lib/gpu/Makefile.linux | grep -v "#CUDA_ARCH" | grep -v " CUDA_ARCH "
CUDA_ARCH = -arch=sm_50
$ grep "CUDA_ARCH" lib/gpu/Makefile.linux | grep -v "#CUDA_ARCH" | grep -v " CUDA_ARCH " | sed 's/sm_.*/sm_86/g'
CUDA_ARCH = -arch=sm_86
$ grep "CUDA_ARCH" lib/gpu/Makefile.linux
#     - Change CUDA_ARCH for your GPU
#CUDA_ARCH = -arch=sm_30
#CUDA_ARCH = -arch=sm_32
#CUDA_ARCH = -arch=sm_35
#CUDA_ARCH = -arch=sm_37
CUDA_ARCH = -arch=sm_50
#CUDA_ARCH = -arch=sm_52

How can I fix that?

mahmood
  • 23,197
  • 49
  • 147
  • 242

1 Answers1

3

Here's a simplified example of your error:

$ echo 'abc -a xyz' | xargs sed 's/abc/123/'
sed: invalid option -- 'a'

# if - isn't present in the stdin data, you might get file errors
$ echo 'abc a xyz' | xargs sed 's/abc/123/'
sed: can't read abc: No such file or directory
sed: can't read a: No such file or directory
sed: can't read xyz: No such file or directory

# you can remove xargs, but then you'll not be able to use -i
$ echo 'abc -a xyz' | sed 's/abc/123/'
123 -a xyz

Try this (replace ip.txt with lib/gpu/Makefile.linux). If it works, then use the -i option.

$ cat ip.txt
#CUDA_ARCH = -arch=sm_50
 CUDA_ARCH = -arch=sm_50
CUDA_ARCH = -arch=sm_50

$ sed -E '/(^|[^# ])CUDA_ARCH/ s/sm_.*/sm_86/' ip.txt
#CUDA_ARCH = -arch=sm_50
 CUDA_ARCH = -arch=sm_50
CUDA_ARCH = -arch=sm_86

sed supports filtering, so no need to use grep here.

/(^|[^# ])CUDA_ARCH/ will match CUDA_ARCH at the start of a line or if it is not preceded by a # or space character.

For such lines, the substitution command will be applied.

If a single regexp won't help and you need multiple conditions, you can use something like /regexp1/ { /regexp2/ {stmts} }. Use /regexp/! to invert the condition.

Sundeep
  • 23,246
  • 2
  • 28
  • 103
  • OK. I used `-Ei` to make changes in file. However `-i` alone doesn't work which is odd. – mahmood Sep 04 '21 at 13:24
  • GNU sed will work with `-i` option without needing argument, but other implementations like BSD won't. See https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux – Sundeep Sep 04 '21 at 13:30