I have code in a script similar to this…
smbconffile="/etc/samba/smb.conf"
sed -i 's/.*[\[CMI\]]/\[CMI\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[LOCAL\]]/\[LOCAL\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[NATIONAL\]]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || "Failed"
this changes the names of the shares in the samba conf (smb.conf) to the CMI$, LOCAL$, NATIONAL$.
the problem i am having is that after the second sed command, sed finds "NATIONAL" but it renames it as "LOCAL$" instead of "NATIONAL$". Does anyone see an issue with the commands?
Any help would be greatly appreciated.
Best Answer
You're mixing character classes (a list of characters inside square brackets) with the smb.conf share names which are surrounded by square bracket literals. Also, the
echo
command is not well-formed: in the case wheresed
exits with a non-zero status, the shell will attempt to invoke the commandFailed
.A few suggestions:
.*
which will remove leading comments, etc.sed
command with multiple statementsYou could use backreferences to avoid retyping the original prefix in the replacement expression (e.g., `[CMI'), but that can make the expressions even harder to read.
Another suggest is to use Perl which has readable grouping and backreferences IMO:
Edit: To clarify, the problem with the original expression with the outer brackets is that you are creating a character class which matches any string containing (in the first case)
[
,C
,M
,I
,]
in any order followed by a]
. For example:Removing the outer brackets removes the character class so the expression will match the exact substring provided.