2

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
user:$6$hcwp49Lr$BjcJYc/nwaufmsOIw4Tw/POaXO4j.0HDLU0:16310:0:99999:7:::
# 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.

2 Answers2

1

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
AProgrammer
  • 2,318
0

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

$6$hcwp49Lr$BjcJYc/nwaufmsOIw4Tw/POaXO4j.0HDLU0

should be replaced with:

XXXXX

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

sed '/^user:/s/:[^:]*/:XXXXX/
' <<\DATA
# junk here
user:$6$hcwp49Lr$BjcJYc/nwaufmsOIw4Tw/POaXO4j.0HDLU0:16310:0:99999:7:::
other:$6$hcwp49Lr$BjcJYc/nwaufmsOIw4Tw/POaXO4j.0HDLU0:16310:0:99999:7:::
user:different stuff in this spot:16310:0:99999:7:::
# junk here
DATA

OUTPUT

# junk here
user:XXXXX:16310:0:99999:7:::
other:$6$hcwp49Lr$BjcJYc/nwaufmsOIw4Tw/POaXO4j.0HDLU0:16310:0:99999:7:::
user:XXXXX:16310:0:99999:7:::
# 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:.

mikeserv
  • 58,310