I am having trouble using sed find/replace with slashes in the find parameter.

Sample contents of test.sh

str=$(sed -n '/^user:/p' /tmp/shadowtest) # find "user:" line in /etc/shadowtest
arr=(${str//:/ }) # explode str with : as delimeter
arr=${arr[1]} # grab the 2nd element
sed -i 's|$arr|XXXXX|g' /tmp/shadowtest # Nothing gets replaced in shadowtest

Sample contents of /tmp/shadowtest

# junk here
# junk here

When I run the script as is, nothing gets replaced in the shadowtest file. But if I change the sed command to something like

sed -i 's|99999|XXXXX|g' /tmp/shadowtest

it works fine.

  • Your using pipe symbols, they should be slashes when your using sed
    – ryekayo
    Aug 29 '14 at 15:09
  • The pipe works via
    – kenster89
    Aug 29 '14 at 15:12
  • Look at AProgrammer's answer and try using double quotes instead. He beat me to the punch.
    – ryekayo
    Aug 29 '14 at 15:13

If you want $arr to be substituted, you need to put it outside single quotes. For instance:

sed -i "s|$arr|XXXXX|g" /tmp/shadowtest

If I understand the purpose of your code correctly, then, in your example case:


should be replaced with:


If this is true, you don't need to involve the shell at all:

sed '/^user:/s/:[^:]*/:XXXXX/
' <<\DATA
# junk here
user:different stuff in this spot:16310:0:99999:7:::
# junk here


# junk here
# junk here

It works in the same way your own does - mostly - in that it addresses only lines that begin with the string user:, but, rather than performing the p function on them, it does the s/// function instead.

It substitutes the string :XXXXX for the first sequence of non-: characters immediately preceded by a : on lines that begin with the string user:.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.