Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: using sed for replacing a "specific place", not a find and replace...

  1. #1
    Join Date
    Apr 2008
    Beans
    7

    Lightbulb using sed for replacing a "specific place", not a find and replace...

    I want to use sed for replacing a "very specific" place in a text file,
    not for doing a "find and replace" of a pattern.

    For example my file is:
    ---------------
    name = john
    surname = smith
    tall = 187.12 cm
    age = 34
    ---------------

    I want to replace "187.12" with something and I know it's address:
    third line, starting from column 8 to 14.

    In general I want to replace the text in
    line "n", beginning column "p" ending column "q"
    of file with something else. How do I do that?

    not insisting for sed, anything portable which works on bash is fine!

    Thank you very much

  2. #2
    Join Date
    Apr 2012
    Beans
    7,256

    Re: using sed for replacing a "specific place", not a find and replace...

    You should be able to address just the nth line specifically e.g. to do command on line 3 only

    Code:
    sed '3command'
    This kind of addressing is most often seen in deletions like sed '5d' (delete fifth line) but can be applied to substitutions as well, so you could find a pattern in the 3rd line consisting of a group of any 7 characters followed by any further 7 characters and replace just the first group - something like

    Code:
    sed '3s/^\(.\{7\}\)\(.\{7\}\)/\1/' file
    If you don't mind giving up a bit of portability you can use GNU sed extensions to get rid of some of the escapes

    Code:
    sed -r '3s/^(.{7})(.{7})/\1/' file

  3. #3
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: using sed for replacing a "specific place", not a find and replace...

    if you want to work with a specific line which has the same context, eg 'tall =' you can also use
    Code:
    '/^tall =/ s/.../.../'
    to modify it. I'd argue that it's safer than expecting a line number.

    I suggest looking into awk too, some classes of problems are pain in the a.. with sed (it's dumb and regexes are sometimes tedious to write correctly), while awk understands the structure of the text more and offers tons of convenience. Not saying that it will work better here in this case, but the more tools the better, one can choose appropriate tool to the task at hand.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  4. #4
    Join Date
    Apr 2012
    Beans
    7,256

    Re: using sed for replacing a "specific place", not a find and replace...

    Agreed - sed can rapidly end up looking like an explosion in a punctuation factory, especially when lots of escaping is required - hard to read and maintain

  5. #5
    Join Date
    Feb 2006
    Location
    Vancouver, BC, Canada
    Beans
    318

    Re: using sed for replacing a "specific place", not a find and replace...

    You can modify the characters at a particular index within a line like this:

    Code:
    bob@cob:~$ cat /tmp/file
    name = john
    surname = smith
    tall = 187.12 cm
    age = 34
    
    bob@cob:~$ perl -pe 'if($.=="3"){substr($_,7,6,"ABCDEF");} ' /tmp/file
    name = john
    surname = smith
    tall = ABCDEF cm
    age = 34
    Some explanation:
    The variable named $. is the current line number.
    The substr() function takes the following arguments:
    substr EXPR,OFFSET,LENGTH,REPLACEMENT
    For more information, run "perldoc -f substr"
    Perl's "-p" flag iterates through each line in the given input file, running the given code before printing the line.
    The variable named "$_" holds the contents of the current line.

  6. #6
    Join Date
    Apr 2011
    Location
    Maryland
    Beans
    1,461
    Distro
    Kubuntu 12.04 Precise Pangolin

    Re: using sed for replacing a "specific place", not a find and replace...

    Quote Originally Posted by stylishpants View Post
    You can modify the characters at a particular index within a line like this:

    Code:
    bob@cob:~$ cat /tmp/file
    name = john
    surname = smith
    tall = 187.12 cm
    age = 34
    
    bob@cob:~$ perl -pe 'if($.=="3"){substr($_,7,6,"ABCDEF");} ' /tmp/file
    name = john
    surname = smith
    tall = ABCDEF cm
    age = 34
    Some explanation:
    The variable named $. is the current line number.
    The substr() function takes the following arguments:
    substr EXPR,OFFSET,LENGTH,REPLACEMENT
    For more information, run "perldoc -f substr"
    Perl's "-p" flag iterates through each line in the given input file, running the given code before printing the line.
    The variable named "$_" holds the contents of the current line.
    Hmmm...that's pretty convenient. I going to keep that idea handy as I'm sure I can use something along those lines from time to time. I'm working on learning Perl at the moment, but pretty far behind as I just can't find the time to focus on it (too many things going on at the moment!).

    Agreed - sed can rapidly end up looking like an explosion in a punctuation factory, especially when lots of escaping is required - hard to read and maintain
    Ha!!! So true. I think that's why I've been so intimidated about learning sed! Very funny!

  7. #7
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: using sed for replacing a "specific place", not a find and replace...

    perl to me is like awk on steroids, too bad it looks like a randomly generated sequence of characters when pushed to the limits
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  8. #8
    Join Date
    Apr 2008
    Beans
    7

    Re: using sed for replacing a "specific place", not a find and replace...

    Quote Originally Posted by steeldriver View Post
    You should be able to address just the nth line specifically e.g. to do command on line 3 only

    Code:
    sed '3command'
    This kind of addressing is most often seen in deletions like sed '5d' (delete fifth line) but can be applied to substitutions as well, so you could find a pattern in the 3rd line consisting of a group of any 7 characters followed by any further 7 characters and replace just the first group - something like

    Code:
    sed '3s/^\(.\{7\}\)\(.\{7\}\)/\1/' file
    If you don't mind giving up a bit of portability you can use GNU sed extensions to get rid of some of the escapes

    Code:
    sed -r '3s/^(.{7})(.{7})/\1/' file
    Thanks, this will work for me!


    Quote Originally Posted by Vaphell View Post
    if you want to work with a specific line which has the same context, eg 'tall =' you can also use
    Code:
    '/^tall =/ s/.../.../'
    to modify it. I'd argue that it's safer than expecting a line number.

    I suggest looking into awk too, some classes of problems are pain in the a.. with sed (it's dumb and regexes are sometimes tedious to write correctly), while awk understands the structure of the text more and offers tons of convenience. Not saying that it will work better here in this case, but the more tools the better, one can choose appropriate tool to the task at hand.
    Agree using tall is than giving just a line. But problem is that I might have several lines like "tall = "

    Quote Originally Posted by stylishpants View Post
    You can modify the characters at a particular index within a line like this:

    Code:
    bob@cob:~$ cat /tmp/file
    name = john
    surname = smith
    tall = 187.12 cm
    age = 34
    
    bob@cob:~$ perl -pe 'if($.=="3"){substr($_,7,6,"ABCDEF");} ' /tmp/file
    name = john
    surname = smith
    tall = ABCDEF cm
    age = 34
    Some explanation:
    The variable named $. is the current line number.
    The substr() function takes the following arguments:
    substr EXPR,OFFSET,LENGTH,REPLACEMENT
    For more information, run "perldoc -f substr"
    Perl's "-p" flag iterates through each line in the given input file, running the given code before printing the line.
    The variable named "$_" holds the contents of the current line.
    Thanks a lot! I am also really interested to learn a bit of perl. You settled me at the start line

    I would like to thank all!

  9. #9
    Join Date
    Apr 2011
    Location
    Maryland
    Beans
    1,461
    Distro
    Kubuntu 12.04 Precise Pangolin

    Re: using sed for replacing a "specific place", not a find and replace...

    Quote Originally Posted by Vaphell View Post
    perl to me is like awk on steroids, too bad it looks like a randomly generated sequence of characters when pushed to the limits
    Indeed it is, which is why I've sort of started down the path of learning it instead of Python, which was my original goal. Considering that Larry Wall invented it since there was some things he couldn't do with AWK, I guess the relationship makes sense.

    It can get just about as ugly as sed, though....you're right. In fact, for a good laugh, check out the "Obfuscated Perl Contest", which I don't think is held anymore. Here's an example of some winning code:

    Code:
    @P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
    @p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
    ($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
    close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print

  10. #10
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: using sed for replacing a "specific place", not a find and replace...

    that's why i am not too motivated to get into perl. While it has serious advantages like native multiline operations, which need to be hacked hard in case of other tools, or a crapton of modules it's not very self-documenting. When too much logic is compressed into too few bytes you can get lost reading code you wrote just a month ago.
    Not that i use python much since i went the road of quick and dirty hacking with bash et consortes, but i imagine it's relative verbosity lends itself better to maintaining code.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

Page 1 of 2 12 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

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