0

I am trying to change a .profile (Ubuntu) as follows:

Original .profile file section:

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists

I want to change the above code to look like this:

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

BASHRC_CONFIG_DIR=/netshare/users/$USER/

if [ -f "$BASHRC_CONFIG_DIR/.bashrc" ]; then
    . "$BASHRC_CONFIG_DIR/.bashrc"
fi



# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$BASHRC_CONFIG_DIR/.bashrc" ]; then
        . "$BASHRC_CONFIG_DIR/.bashrc"
    else
        if [ -f "$HOME/.bashrc" ]; then
            . "$HOME/.bashrc"
        fi
    fi
fi

# set PATH so it includes user's private bin if it exists

I've tried so many iterations of sed to replace the block in the top file with a file that contains the bottom section and am bashing my head against the wall. Does anyone have any sed (or awk) knowledge they can impart on me so that I may achieve this and put an ice pack on my head?

I've tried this:

sed -n \
  -e "1,/umask 022/ p" \
  -e"/set PATH/,$ p" \
  -e "/umask 022/ r profile_insertion" \
  /home/username/.profile.bak

And this:

sed -i 's/(umask 022).*(#set PATH)/\1 profile_insertion \2/g' /home/username/.profile

(profile_insertion contains the text I want to put in place)

  • 1
    Please do add your attempted code in your question, which is highly encouraged on SO(for questioners to put their efforts in their question), thank you. – RavinderSingh13 Feb 19 '21 at 18:47
  • `sed` is the best tool for doing simple `s/old/new/` replacements on individual lines. If you have to do anything more than that (as you are) you're much better off using `awk` for clarity, robustness, efficiency, portability, ease of maintenance/enhancement, etc. – Ed Morton Feb 20 '21 at 14:12
  • Obviously it took you longer to post this question that it would have taken to just edit the .profile by hand so - why are you trying to write a script to do this? If the answer is "to make the change to 100 .profiles" then can you really rely on all those .profiles having exactly the same strings to match on (e.g. `umask 022` and `#set PATH`) in exactly the same places as the .profile in your question? If the .profile's are always common why not just edit 1 .profile and copy it to the other 99? – Ed Morton Feb 20 '21 at 14:15

1 Answers1

0

If you can recast it as chopping off the top of the file and replacing it, you can use awk (see Remove all lines before a match with sed).

Make sure profileinsertion has everything you'd need from the beginning of the file, and use something like:

cp profileinsertion profile.out; awk '/set PATH so it/{p++;if(p==1){next}}p' /home/username/.profile >> profile.out

...changing your filenames as needed.

Rick M
  • 1,012
  • 1
  • 7
  • 9
  • BRILLIANT! This worked! Thank you so much!! – FrustratedCoder Feb 19 '21 at 21:16
  • You're welcome, glad to help! If you don't mind, please mark it as 'accepted' by clicking the green check mark (and upvote if you like, too). This helps keep the focus on older SO questions which still don't have answers. Thanks, and good luck! – Rick M Feb 19 '21 at 21:41