Search code examples
bashperlsearchstr-replace

Search sub string then Replace Line in a file without regex


I want to run a script to search the /etc/bash.bashrc file for the substring

PS1=

and replace the entire line with:

 PS1='\[\e[36m\]\h\[\e[m\]\[\e[33m\]@\[\e[m\]\[\e[33m\]\u\[\e[m\]:\[\e[32m\]\W\[\e[m\]>\\$ '

This new line is intended to change the cli prompt.

I have tried and tried sed in a bash script but I couldn't get the regex right.

[Edit] This code now works:

#!/bin/bash

custom_prompt='${debian_chroot:+($debian_chroot)}\[\e[36;40m\]\u\[\e[m\]\[\e[93m\]@\[\e[m\]\[\e[36m\]\h\[\e[m\]:\[\e[92m\]\w\[\e[m\]\[\e[92m\]\\$\[\e[m\]\[\e[93m\]>\[\e[m\]\'

### Setup Bash Prompt
# replace each \ for double \\ in the prompt string
sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')

# add this to  /etc/bashrc for global effect
sed  -i "s/PS1=.*/PS1=\"$sed_custom_prompt\"/" testrc

The only problem is that it does PS1= " string " rather than PS1 = ' string ' with back tics.

I need a simple old fashioned non-regex script that finds a string and replaces a line in a file. Regex can find the string but my original statement messed up the substitution.

I don't care if it is perl, awk or bash. I just need something that works.


Solution

  • You should escape every \ to make sure they aren't lost.

    EDIT: The PS1 string should be wrapped with double quotes as well.

    
    $ custom_prompt="\[\e[36m\]\h\[\e[m\]\[\e[33m\]@\[\e[m\]\[\e[33m\]\u\[\e[m\]:\[\e[32m\]\W\[\e[m\]>\\$ "
    $ sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')
    $ sed -i "s/PS1=.*/PS1=\"$sed_custom_prompt\"/" testrc
    $ source testrc
    laptop@user:~>$
    

    The following code works on my laptop. The problem was in last \ character in the string of your PS1 variable (I removed it):

    #! /bin/bash
    custom_prompt='${debian_chroot:+($debian_chroot)}\[\e[36;40m\]\u\[\e[m\]\[\e[93m\]@\[\e[m\]\[\e[36m\]\h\[\e[m\]:\[\e[92m\]\w\[\e[m\]\[\e[92m\]\\$\[\e[m\]\[\e[93m\]>\[\e[m\] '
    
    ### Setup Bash Prompt
    # replace each \ for double \\ in the prompt string
    sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')
    
    # add this to  /etc/bashrc for global effect
    sed -i  "s/PS1=.*/PS1='$sed_custom_prompt'/" testrc
    
    exit 0
    

    p.s. I personally like to add the time to the PS1 so I know how long ago a command is exited. Also, you can immediately time stuff if you add it (\D{%H}:\D{%M}).