Find the answer to your Linux question:
Results 1 to 9 of 9
Hi, So the exact situation is that I need to edit my .profile (I'm on OS X) a lot. I have two lines (lines 48 and 49) which I have ...
  1. #1
    Just Joined!
    Join Date
    Feb 2010
    Posts
    4

    Need a script to edit text of file

    Hi,

    So the exact situation is that I need to edit my .profile (I'm on OS X) a lot. I have two lines (lines 48 and 49) which I have to alternate.

    So I'll have to open nano every time I want to uncomment 48 and comment out 49 and vice versa. It gets a bit redundant and tedious after a while.

    Is there a command or script that could help me do this? I tried looking at how to use awk/cut/perl, but I don't really have time to learn an entire scripting language.

    Thanks,

    Cavin

  2. #2
    Linux Engineer GNU-Fan's Avatar
    Join Date
    Mar 2008
    Posts
    935
    A quick way to do this without sed/awk is two have two separate template files and copy the appropriate one to its destination.
    Debian GNU/Linux -- You know you want it.

  3. #3
    Just Joined!
    Join Date
    Aug 2005
    Posts
    9
    Quote Originally Posted by GNU-Fan View Post
    A quick way to do this without sed/awk is two have two separate template files and copy the appropriate one to its destination.
    This would work, and you'd just have to re-source your profile.

    I do something similar, where I edit my profile alot.. so I have an alias to vi to edit my profile.. and then another alias to resource my profile.

    alias epro='vi /home/dmurphy/.profile'
    alias rs='source /home/dmurphy/.profile'

    You could make this all a function so if you're just swapping the two.. you could do something like this (if then syntax could be wrong.. just doing this in my head logically..)
    usage would be swappro 1 or swappro 2

    function swappro () {

    if [ $1 == 1 ] then;
    {
    cp <pathToProfile>/profile1 <pathToProfile>/profile
    source <pathToProfile>/profile
    }
    elseif { $1 == 2 ] then;
    {
    cp <pathToProfile>/profile2 <pathToProfile>/profile
    source <pathToProfile>/profile
    }
    fi
    }

  4. #4
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    This can also be done by using awk. For instance:

    Code:
    #!/usr/bin/awk
    
    if (((NR == 48) || (NR == 49)) && /^#/)
        print substr($0, 1, length($0));
    else if((NR == 48) || (NR == 49))
        print "#" $0;
    This will look at lines 48 and 49 of the file it is applied to and will prepend a "#" if there is none already, and remove the "#" at the beginning if there is one.

    There are some obvious deficiencies, which is that 48 and 49 are hardcoded. However, that is easily fixable by changing it to accept the lines as arguments.

    I also believe that this is a bit superior to the option of multiple profiles because only two lines are affected. With this method, you only need to change your profile in one location, whereas if you keep separate files, you have to make changes in both of them.
    DISTRO=Arch
    Registered Linux User #388732

  5. #5
    Just Joined!
    Join Date
    Aug 2005
    Posts
    9
    excellent solution Cabhan.

    That's what I originally wanted to post.. but I wasn't sure exactly how to simply put it, without using awk/sed and creating a large script, which would've taken me time to figure out.

    The 2 profiles solution is a yucky one at best.

  6. #6
    Just Joined!
    Join Date
    Feb 2010
    Posts
    4
    Quote Originally Posted by Cabhan View Post
    This can also be done by using awk. For instance:

    Code:
    #!/usr/bin/awk
    
    if (((NR == 48) || (NR == 49)) && /^#/)
        print substr($0, 1, length($0));
    else if((NR == 48) || (NR == 49))
        print "#" $0;
    This will look at lines 48 and 49 of the file it is applied to and will prepend a "#" if there is none already, and remove the "#" at the beginning if there is one.

    There are some obvious deficiencies, which is that 48 and 49 are hardcoded. However, that is easily fixable by changing it to accept the lines as arguments.

    I also believe that this is a bit superior to the option of multiple profiles because only two lines are affected. With this method, you only need to change your profile in one location, whereas if you keep separate files, you have to make changes in both of them.
    Thank you.

    I may just be lost on the syntax of how to use it. I tried it like:
    Code:
    ./chprof.awk .profile
    while being in my home directory, but it gives me:
    Code:
    /usr/bin/awk: syntax error at source line 1
     context is
    	 >>> . <<< /chprof
    What am I missing?

  7. #7
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    So I in fact did not test the program I posted here before, and I am not as powerful an awk guru as others, so it doesn't in fact fully work. Sorry about that. This one should work (and you can run it with the ./ syntax like you tried):

    Code:
    #!/usr/bin/awk -f
    
    line1 = 48
    line2 = 49
    
    (((NR == line1) || (NR == line2)) && /^#/) {
        print substr($0, 2, length($0))
        next
    }
    
    (((NR == line1) || (NR == line2))) {
        print "#" $0
        next
    }
    I have also turned the line numbers into variables, so they should be simple to change if your profile changes.

    Also note that this does not actually make one line commented and the other uncommented. Instead, it looks at these two lines and comments them if they are uncommented, and uncomments them if they are commented. Therefore, you can easily get this script to not work entirely as intended, but as long as you don't change the commenting of the lines on your own, this should work fine.

    Sorry about the screwy solution earlier. Hope this helps!
    DISTRO=Arch
    Registered Linux User #388732

  8. #8
    Just Joined!
    Join Date
    Feb 2010
    Posts
    4
    Quote Originally Posted by Cabhan View Post
    So I in fact did not test the program I posted here before, and I am not as powerful an awk guru as others, so it doesn't in fact fully work. Sorry about that. This one should work (and you can run it with the ./ syntax like you tried):

    Code:
    #!/usr/bin/awk -f
    
    line1 = 48
    line2 = 49
    
    (((NR == line1) || (NR == line2)) && /^#/) {
        print substr($0, 2, length($0))
        next
    }
    
    (((NR == line1) || (NR == line2))) {
        print "#" $0
        next
    }
    I have also turned the line numbers into variables, so they should be simple to change if your profile changes.

    Also note that this does not actually make one line commented and the other uncommented. Instead, it looks at these two lines and comments them if they are uncommented, and uncomments them if they are commented. Therefore, you can easily get this script to not work entirely as intended, but as long as you don't change the commenting of the lines on your own, this should work fine.

    Sorry about the screwy solution earlier. Hope this helps!
    Thank you for the effort though! It's appreciated.

    Unfortunately now, it doesn't seem to be doing anything at all... When I run it:
    Code:
    ./chprof.awk .profile
    (in my home dir btw)

    it prints the contents of my .profile, but each line is printed twice.

    So, for example, I have an alias:

    Code:
    alias texmate='open -a TextMate'
    and it prints:

    Code:
    alias texmate='open -a TextMate'
    alias texmate='open -a TextMate'

  9. #9
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    Modified awk code as follows:
    Code:
    #!/usr/bin/env bash
    
    # @(#) s1	Demonstrate toggle commenting lines.
    
    # Infrastructure details, environment, commands for forum posts. 
    set +o nounset
    LC_ALL=C ; LANG=C ; export LC_ALL LANG
    echo ; echo "Environment: LC_ALL = $LC_ALL, LANG = $LANG"
    echo "(Versions displayed with local utility \"version\")"
    c=$( ps | grep $$ | awk '{print $NF}' )
    version >/dev/null 2>&1 && s=$(_eat $0 $1) || s=""
    [ "$c" = "$s" ] && p="$s" || p="$c"
    version >/dev/null 2>&1 && version "=o" $p awk
    set -o nounset
    echo
    
    echo " awk procedure a1:"
    cat a1
    
    FILE=${1-data1}
    
    echo
    echo " Data file $FILE:"
    cat $FILE
    
    echo
    echo " Results:"
    ./a1 $FILE
    
    exit 0
    producing:
    Code:
    % ./s1
    
    Environment: LC_ALL = C, LANG = C
    (Versions displayed with local utility "version")
    OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
    Distribution        : Debian GNU/Linux 5.0 
    GNU bash 3.2.39
    GNU Awk 3.1.5
    
     awk procedure a1:
    #!/usr/bin/awk -f
    
    BEGIN	{ line1 = 2 ; line2 = 3 }
    
    (((NR == line1) || (NR == line2)) && /^#/) {
        print substr($0, 2, length($0))
        next
    }
    
    (((NR == line1) || (NR == line2))) {
        print "#" $0
        next
    }
    
    	{ print }
    
     Data file data1:
    foo
    #bar
    baz
    qux
    
     Results:
    foo
    bar
    #baz
    qux
    Best wishes ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...