Find the answer to your Linux question:
Results 1 to 5 of 5
I want to edit a text file to search for a piece of text, then change the lines following it. For example, in the file: This is not it 1 ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Feb 2012
    Posts
    7

    Change 1st occurence of text after finding another line of text


    I want to edit a text file to search for a piece of text, then change the lines following it. For example, in the file:

    This is not it
    1
    2
    3
    This is not it either
    1
    2
    3
    This is the one
    1
    2
    3
    This is also not it
    1
    2
    3

    I want to search on "This is the one", and change the next "2" to a "0", but only the one immediately following the search term.

    Can anyone point me to the right tool(s) for the job?

    Thanks,
    Mike

  2. #2
    Just Joined!
    Join Date
    Aug 2011
    Posts
    18
    Ok... I'm TERRIBLE at regex, but I did write a script that does what you want without using regex. Ideally someone with regex expertise will come along with some code that is even niftier.

    Code:
    #!/usr/bin/env ruby
    
    file = File.open("input.txt", "r") # open file for reading
    contents = file.read
    file.close
    
    pattern = "This is the one"
    
    #  Find where the next line item will be
    pattern_position_end = contents.index(pattern) + pattern.length + 1
    
    subsequent_pattern_position = contents.index("2", pattern_position_end)
    
    contents[subsequent_pattern_position] = "0"
    
    puts contents
    
    # You don't need this if you use stdout redirection, eg `./main.rb > output.txt`
    File.open("input.txt", "w+") do |f|
      f.write contents
    end
    To install ruby on your machine, you might want to install rvm... or install a ruby package, `apt install ruby1.9`

  3. #3
    Just Joined!
    Join Date
    Aug 2011
    Posts
    18
    Here's a regex example too, I think it's up to snuff... but i'm kind of a regex

    /This is the one.*?(2)/m
    Any text between the slashes will be searched for,
    .* means match any character, and do so any number of times
    ? means don't be greedy when matching though, the first occurrence of '2' is where you should stop
    (2) means capture the '2' character

    and that m at the end tells .* that it can count new line characters.

    You can play around with this sort of thing at rubular.com

    Code:
    #!/usr/bin/env ruby
    require 'pry'
    
    words_to_match = "This is the one"
    char_to_replace = "2"
    overwrite_value = "0"
    
    file = File.open("input.txt", "r") # open file for reading
    contents = file.read
    file.close
    
    pattern = /#{words_to_match}.*?(#{char_to_replace})/m
    
    position = pattern.match(contents).begin(1) # get the beginning index of the thing we captured in that regex statement
    
    contents[position] = overwrite_value
    
    puts contents
    
    # You don't need this if you use stdout redirection, eg `./main.rb > output.txt`
    #File.open("input.txt", "w+") do |f|
    #  f.write contents
    #end
    Let me know if it gives you trouble.

  4. #4
    Linux Newbie
    Join Date
    Jun 2012
    Location
    SF Bay area
    Posts
    173
    Awk is pretty good at this sort of thing, since it's essentially a programming language designed around a state machine...

    Code:
    #!/bin/awk -f
    
    /This is the one/ { change = 1; } 
    
    $1 == "2" && change { $0 = 0; change = 0;} 
    
    { print; }
    Last edited by cnamejj; 09-18-2012 at 01:09 AM. Reason: typo, requestor wanted one change, I coded a different one

  5. #5
    Just Joined!
    Join Date
    Feb 2012
    Posts
    7
    Thank you so much, I really appreciate the assistance. I think I'm going to use the "awk" script, but I certainly will play with the scripts that hobuscorpus so kindly provided.

Posting Permissions

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