sed with backslash in replacement text.

Status
Not open for further replies.

Janus Ng

Explorer
Joined
Apr 10, 2016
Messages
63
I have just installed FreeNAS for a week. There were 2 updates after my initial installation. I appreciate it quick development very much. Thanks developers!

As I have many files with names in many languages, I prefer to set the locale in bash to utf-8. This feature is useful to all users; hence, I change the /etc/login.conf, add a line ":lang=en_US.UTF-8:\" to default setting such as:
default:\
:passwd_format=sha512:\
...
becomes
default:\
:lang=en_US.UTF-8:\
:passwd_format=sha512:\
...

However, I found that the file is rest every time the OS is updated. That's why I wrote a shell script to accomplish the task. I can run it just after an update next time. The script is listed as following.
#!/bin/bash
d=$(date +%Y-%m-%d)
f=/etc/login.conf
i=0
n=$f.$d.$i
while [ -a "$n" ]; do
i=$(($i + 1))
n=$f.$d.$i
done

sed -i .$d.$i -E 's/^default:\\$/&\'$'\n'$'\t:lang=en_US.UTF-8:\\/g' $f
echo
echo $f backed up to $n
echo $f is updated with en_US.UTF-8 locale.

cap_mkdb /etc/login.conf
echo
echo Please relogin to use new settings.

However, it reports the following error.
sed: 2: "s/^default:\\$/&\
:lan ...": unterminated substitute in regular expression
sed complaint about the backslashes in the substitute text.

Please help me out! Thanks a ton!
 
Last edited:

jgreco

Resident Grinch
Joined
May 29, 2011
Messages
18,680
\\/g strikes me as wrong. echo your expression in the shell to find out what is being passed to sed.
 

jgreco

Resident Grinch
Joined
May 29, 2011
Messages
18,680
That was it, then, huh?

With all the quoting and stuff like that involved in shell scripting, it sometimes gets hard to see through multiple layers, and I find that seeing what is actually being passed to the underlying utilities (grep, sed, whatever) is sometimes extremely helpful in debugging quoting issues.
 

Janus Ng

Explorer
Joined
Apr 10, 2016
Messages
63
Yeah, your advice woke me up where the problem is, jgreco.

I have taken the advice on stackoverflow, just write it literally and made it platform independent as
sed -i .$d.$i -E 's/^default:\\$/\\\
:Lang=en_US.UTF-8:\\/g' $f
Thank you!
 

anodos

Sambassador
iXsystems
Joined
Mar 6, 2014
Messages
9,554
Yeah, your advice woke me up where the problem is, jgreco.

I have taken the advice on stackoverflow, just write it literally and made it platform independent as
sed -i .$d.$i -E 's/^default:\\$/\\\
:Lang=en_US.UTF-8:\\/g' $f
Thank you!
You know, you can use other characters as delimiters to avoid 'leaning toothpick syndrome'
 

Janus Ng

Explorer
Joined
Apr 10, 2016
Messages
63
You know, you can use other characters as delimiters to avoid 'leaning toothpick syndrome'

Can you enlighten me on how to use other characters as delimiters? I didn't know it was possible.
By the way, is it possible to prevent it from adding duplicated lines on consecutive runs? Thanks!
 

jgreco

Resident Grinch
Joined
May 29, 2011
Messages
18,680
Can you enlighten me on how to use other characters as delimiters? I didn't know it was possible.
By the way, is it possible to prevent it from adding duplicated lines on consecutive runs? Thanks!

The character after the "s" is the delimiter. So "s@one@two@", "s/one/two/", "s,one,two," are all equivalent. Special care need be taken that you pick a delimiter that isn't part of your expression or even more special fun can result.
 
Status
Not open for further replies.
Top