LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-19-2009, 01:14 AM   #1
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Rep: Reputation: 15
BASH: how to substitute just one occurency of a pattern in a text file


I want to know if it's possible to use 'sed' to substitute just the first occurency of a searched pattern in the file, so if I have:

text
text PATTERN
text
PATTERN
text PATTERN text
text


is there a way of substituting the first occurency of PATTERN in the file? So that at the end I have:


text
text SUBSTITUTED PATTERN
text
PATTERN
text PATTERN text
text
 
Old 11-19-2009, 01:37 AM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
If you want to do it using sed then it is a sed question not a bash question (so the thread title is misleading and I cannot help you).

If you are happy to do it in bash script then it is easy but will take longer to execute than when done by sed. That may or may not be a problem, depending on the size of the file.
 
Old 11-19-2009, 01:47 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
How do I match only the first occurrence of a pattern?

From the sed faq.
 
Old 11-19-2009, 02:09 AM   #4
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
@OP : awk,sed etc are just tools to help your work. What's more important is to get your algorithm and steps to solve the problem right. You only want to substitute the first occurrence. That means you can set a toggle flag to turn substitution "off" when the first pattern is found
Code:
#!/bin/bash
toggle=0
while read -r line
do
    [ "$toggle" -eq 1 ] && echo $line && continue
    if [ "$toggle" -eq 0 ] ; then
        case $line in
            *PATTERN*) 
                    line=${line/PATTERN/SUBSTITUTED}
                    toggle=1
                    ;;
        esac
    fi
    echo $line
done <"file"
output
Code:
# ./shell.sh
text
text SUBSTITUTED
text
PATTERN
text PATTERN text
text
i think the code is self explanatory. read up more on shell scripting (see my sig).
 
Old 11-19-2009, 02:32 AM   #5
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Original Poster
Rep: Reputation: 15
Hi guys,

sorry for the confusion. The script I'm writing is a .sh file and I'm open to any solution. I just wrote 'with sed' because it is the only command I was using until now.

@David: Thanks for the link! I just tried to use:

sed '0,/RE/s//to_that/' file to change only the first match, but it didn't work.

I wrote in my script:

sed '0,/<declaration>/s//<declaration>\nint p_covg['$access_array_size'];/' file.xml


The pattern I want to find is <declaration> and it should be substituted by <declaration>\nint p_covg['$access_array_size'];, where access_array_size is an integer.


And the text in the file.xml is the following:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE nta PUBLIC '-//Uppaal Team//DTD Flat System 1.1//EN' 'http://www.it.uu.se/research/group/darts/uppaal/flat-1_1.dtd'>
<nta>
<declaration>
clock global;
broadcast chan dummybchannel;
...



Would you know why it doesn't work?
 
Old 11-19-2009, 03:01 AM   #6
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Original Poster
Rep: Reputation: 15
Hi Ghostdog,

nice that you are answering again, thanks. I used your idea but it doesn't save the changes in the original file. What do I need to do, so that the changes are saved?
 
Old 11-19-2009, 03:05 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

It looks like this: sed '0,/<declaration>/s//<declaration>\nint p_covg['$access_array_size'];/' file.xml
is not correct, you are missing the part between the red slashes.

The <declaration> part should be there:

sed '0,/<declaration>/s/<declaration>/<declaration>\nint p_covg['$access_array_size'];/' file.xml

Hope this helps.
 
Old 11-19-2009, 03:16 AM   #8
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Original Poster
Rep: Reputation: 15
You were right druuna. It works now
Thanks a lot!
 
Old 11-19-2009, 03:31 AM   #9
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by carolflb View Post
doesn't save the changes in the original file. What do I need to do, so that the changes are saved?
redirect to a file and rename it back.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to replace string pattern with multi-line text in bash script? brumela Linux - Newbie 6 04-21-2011 06:56 AM
[SOLVED] BASH - how to substitute many lines in a text file at once carolflb Linux - Newbie 6 10-20-2009 01:28 PM
[SOLVED] BASH - how to substitute many lines in a text file at once carolflb Programming 2 10-20-2009 10:21 AM
substitute a pattern only if some other pattern is present raghu123 Programming 3 06-26-2009 06:53 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 01:59 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration